From e313297427c8061b82b1218972b2830c5b01ed0e Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 08:47:42 -0700 Subject: [PATCH 01/20] Format README for packaging. --- README.md | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3a852e2..5e2aa63 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,30 @@ -Autofac.Mef -=========== +# Autofac.Mef -Managed Extensibility Framework (MEF) integration for Autofac IoC +Managed Extensibility Framework (MEF) integration for [Autofac](https://autofac.org). -[![Build status](https://ci.appveyor.com/api/projects/status/404h0j4gj3qyn09a?svg=true)](https://ci.appveyor.com/project/Autofac/autofac-bwvcu) [![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/autofac/Autofac.Mef) +[![Build status](https://ci.appveyor.com/api/projects/status/404h0j4gj3qyn09a?svg=true)](https://ci.appveyor.com/project/Autofac/autofac-bwvcu) + +Please file issues and pull requests for this package [in this repository](https://github.com/autofac/Autofac.Mef/issues) rather than in the Autofac core repo. + +- [Documentation](https://autofac.readthedocs.io/en/latest/integration/mef.html) +- [NuGet](https://www.nuget.org/packages/Autofac.Mef) +- [Contributing](https://autofac.readthedocs.io/en/latest/contributors.html) +- [Open in Visual Studio Code](https://open.vscode.dev/autofac/Autofac.Mef) + +## Quick Start + +The Autofac/MEF integration allows MEF catalogs to be registered with the `ContainerBuilder` using the `RegisterComposablePartCatalog()` extension method. If you register a component using MEF and want to provide Autofac components into that MEF component, use the `Exported()` extension. + +```c# +var builder = new ContainerBuilder(); +var catalog = new DirectoryCatalog(@"C:\MyExtensions"); +builder.RegisterComposablePartCatalog(catalog); +builder.RegisterType() + .Exported(x => x.As().WithMetadata("SomeData", 42)); +``` + +Check out the [Autofac MEF integration documentation](https://autofac.readthedocs.io/en/latest/integration/mef.html) for more information. + +## 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). From 43cdb816f85c9c2ffaa9a6f6aaeda7022bace0d3 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 08:47:49 -0700 Subject: [PATCH 02/20] Upgrade SDK for build. --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index ebf25ba..49d2255 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "3.1.412", + "version": "6.0.300", "rollForward": "latestFeature" } } From aa77a538eb061be6f87b6d746ab797f95ef7bae6 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 08:49:37 -0700 Subject: [PATCH 03/20] Publish symbol packages; Semver => 6.1.0. --- appveyor.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 1ef5d28..4953e83 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,9 +1,9 @@ image: Ubuntu -version: 6.0.1.{build} +version: 6.1.0.{build} dotnet_csproj: - version_prefix: '6.0.1' + version_prefix: "6.1.0" patch: true file: 'src\**\*.csproj' @@ -20,20 +20,20 @@ nuget: clone_depth: 1 -test: off +test: false build_script: - pwsh: .\build.ps1 artifacts: -- path: artifacts\packages\**\*.nupkg - name: MyGet + - path: artifacts\packages\**\*.*nupkg + name: MyGet + type: NuGetPackage deploy: -- provider: NuGet - server: https://www.myget.org/F/autofac/api/v2/package - api_key: - secure: xUXExgVAagrdEicCjSxsQVrwiLo2TtnfqMbYB9Cauq2cpbm/EVz957PBK0v/GEYq - skip_symbols: true - symbol_server: https://www.myget.org/F/autofac/symbols/api/v2/package - artifact: MyGet + - provider: NuGet + server: https://www.myget.org/F/autofac/api/v2/package + symbol_server: https://www.myget.org/F/autofac/api/v2/package + api_key: + secure: xUXExgVAagrdEicCjSxsQVrwiLo2TtnfqMbYB9Cauq2cpbm/EVz957PBK0v/GEYq + artifact: MyGet From 3a16e3b664a8fd19282e87d4f8357eea956c6c71 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 09:30:39 -0700 Subject: [PATCH 04/20] Update build and metadata to .NET 6. --- .editorconfig | 9 +- .vscode/settings.json | 11 +- .vscode/tasks.json | 19 +++ NuGet.config | 5 +- build.ps1 | 17 ++- build/Analyzers.ruleset | 4 +- build/Autofac.Build.psm1 | 45 ++---- build/Test.ruleset | 70 ++++++++++ .../Autofac.Integration.Mef.csproj | 130 ++++++++++-------- .../ContractBasedServiceResources.Designer.cs | 11 +- ...ataRegistrationSourceResources.Designer.cs | 11 +- ...egistrationExtensionsResources.Designer.cs | 11 +- ...ataRegistrationSourceResources.Designer.cs | 11 +- .../ReflectionExtensionsResources.Designer.cs | 11 +- .../Autofac.Integration.Mef.Test.csproj | 33 +++-- 15 files changed, 238 insertions(+), 160 deletions(-) create mode 100644 build/Test.ruleset diff --git a/.editorconfig b/.editorconfig index 2920f1f..9f1a417 100644 --- a/.editorconfig +++ b/.editorconfig @@ -48,7 +48,7 @@ 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 = suggestion +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 @@ -56,7 +56,7 @@ 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 = suggestion +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 @@ -64,7 +64,7 @@ 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 = suggestion +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 @@ -72,7 +72,7 @@ dotnet_naming_symbols.static_readonly_fields.required_modifiers = static, readon 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 = suggestion +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 @@ -128,6 +128,7 @@ 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 diff --git a/.vscode/settings.json b/.vscode/settings.json index a903a89..9371753 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,11 @@ { + "cSpell.words": [ + "autofac", + "browsable", + "cref", + "xunit" + ], "dotnet-test-explorer.testProjectPath": "test/**/*Test.csproj", "omnisharp.enableEditorConfigSupport": true, - "omnisharp.enableRoslynAnalyzers": true, - "cSpell.words": [ - "Xunit" - ] + "omnisharp.enableRoslynAnalyzers": true } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d52dc9b..4c317c5 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,6 +3,7 @@ { "args": [ "build", + "${workspaceFolder}/Autofac.Mef.sln", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], @@ -17,6 +18,24 @@ }, "problemMatcher": "$msCompile", "type": "shell" + }, + { + "args": [ + "test", + "${workspaceFolder}/Autofac.Mef.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary", + "--filter", + "FullyQualifiedName!~Benchmark" + ], + "command": "dotnet", + "group": { + "isDefault": true, + "kind": "test" + }, + "label": "test", + "problemMatcher": "$msCompile", + "type": "process" } ], "version": "2.0.0" diff --git a/NuGet.config b/NuGet.config index cfd4c99..6909bb1 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,11 +1,12 @@ - + - + + diff --git a/build.ps1 b/build.ps1 index cab3862..eedeaa2 100644 --- a/build.ps1 +++ b/build.ps1 @@ -19,12 +19,17 @@ try { Remove-Item $artifactsPath -Force -Recurse } - # Install dotnet CLI - Install-DotNetCli -Version $sdkVersion - - foreach ($additional in $globalJson.additionalSdks) - { - Install-DotNetCli -Version $additional; + # Install dotnet SDK versions during CI. In a local build we assume you have + # everything installed; on CI we'll force the install. If you install _any_ + # SDKs, you have to install _all_ of them because you can't install SDKs in + # two different locations. dotnet CLI locates SDKs relative to the + # executable. + if ($Null -ne $env:APPVEYOR_BUILD_NUMBER) { + Install-DotNetCli -Version $sdkVersion + foreach ($additional in $globalJson.additionalSdks) + { + Install-DotNetCli -Version $additional; + } } # Write out dotnet information diff --git a/build/Analyzers.ruleset b/build/Analyzers.ruleset index 3a625fb..4d4e23d 100644 --- a/build/Analyzers.ruleset +++ b/build/Analyzers.ruleset @@ -34,9 +34,7 @@ - - - + diff --git a/build/Autofac.Build.psm1 b/build/Autofac.Build.psm1 index ba3f5ec..fa53ec8 100644 --- a/build/Autofac.Build.psm1 +++ b/build/Autofac.Build.psm1 @@ -5,11 +5,11 @@ # 4: dotnet / NuGet package restore failure <# - .SYNOPSIS - Gets the set of directories in which projects are available for compile/processing. +.SYNOPSIS + Gets the set of directories in which projects are available for compile/processing. - .PARAMETER RootPath - Path where searching for project directories should begin. +.PARAMETER RootPath + Path where searching for project directories should begin. #> function Get-DotNetProjectDirectory { [CmdletBinding()] @@ -34,25 +34,6 @@ function Install-DotNetCli { [string] $Version = "Latest" ) - - if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue)) { - $installedVersions = dotnet --list-sdks - foreach ($sdkListLine in $installedVersions) - { - $splitParts = $sdkListLine.Split(" "); - - $versionPart = $splitParts[0]; - $globalInstallLocation = $splitParts[1].Replace("[", "").Replace("]", "") - - if ($versionPart -eq $Version) - { - Write-Message ".NET Core SDK version $Version is already installed in $globalInstallLocation" - Add-Path "$globalInstallLocation" - return; - } - } - } - Write-Message "Installing .NET SDK version $Version" $callerPath = Split-Path $MyInvocation.PSCommandPath @@ -103,7 +84,7 @@ function Add-Path { if ($pathValues -Contains $Path) { return; } - + $env:PATH = "${Path}${pathSeparator}$env:PATH" } @@ -134,17 +115,17 @@ function Invoke-DotNetBuild { } <# - .SYNOPSIS - Invokes the dotnet utility to package a project. +.SYNOPSIS + Invokes the dotnet utility to package a project. - .PARAMETER ProjectDirectory - Path to the directory containing the project to package. +.PARAMETER ProjectDirectory + Path to the directory containing the project to package. - .PARAMETER PackagesPath - Path to the "artifacts/packages" folder where packages should go. +.PARAMETER PackagesPath + Path to the "artifacts/packages" folder where packages should go. - .PARAMETER VersionSuffix - The version suffix to use for the NuGet package version. +.PARAMETER VersionSuffix + The version suffix to use for the NuGet package version. #> function Invoke-DotNetPack { [CmdletBinding()] diff --git a/build/Test.ruleset b/build/Test.ruleset new file mode 100644 index 0000000..5809506 --- /dev/null +++ b/build/Test.ruleset @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Autofac.Integration.Mef/Autofac.Integration.Mef.csproj b/src/Autofac.Integration.Mef/Autofac.Integration.Mef.csproj index 43c2332..56d1ec0 100644 --- a/src/Autofac.Integration.Mef/Autofac.Integration.Mef.csproj +++ b/src/Autofac.Integration.Mef/Autofac.Integration.Mef.csproj @@ -1,40 +1,51 @@  - Managed Extensibility Framework integration for Autofac. Enables MEF catalogs to be loaded by the Autofac container. 0.0.1 - netstandard2.0 - latest - $(NoWarn);IDE0008 - true + Autofac.Integration.Mef + Autofac.Mef + Managed Extensibility Framework integration for Autofac. Enables MEF catalogs to be loaded by the Autofac container. + Copyright © 2015 Autofac Contributors + Autofac Contributors + Autofac + Autofac ../../Autofac.snk true + en-US + + netstandard2.0 + latest + enable + true + ../../build/Analyzers.ruleset + AllEnabledByDefault + enable + Autofac.Mef autofac;di;ioc;dependencyinjection;aspnet;aspnetcore Release notes are at https://github.com/autofac/Autofac.Mef/releases icon.png https://autofac.org MIT + README.md git https://github.com/autofac/Autofac.Mef - Autofac.Mef - en-US - Copyright © 2015 Autofac Contributors - AllEnabledByDefault - ../../build/Analyzers.ruleset true true true - $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - Autofac Contributors - Autofac - Autofac + true + snupkg + + + + + @@ -42,61 +53,58 @@ - - + + all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - All - - + all - - True - True - ContractBasedServiceResources.resx - - - - - - True - True - LazyWithMetadataRegistrationSourceResources.resx - - - - - - True - True - StronglyTypedMetadataRegistrationSourceResources.resx - - - - - - True - True - RegistrationExtensionsResources.resx - - - - - - True - True - RegistrationExtensionsResources.resx - + + + ResXFileCodeGenerator + ContractBasedServiceResources.Designer.cs + ContractBasedServiceResources.Designer.cs + CSharp + Autofac.Integration.Mef + ContractBasedServiceResources + + + ResXFileCodeGenerator + LazyWithMetadataRegistrationSourceResources.Designer.cs + LazyWithMetadataRegistrationSourceResources.Designer.cs + CSharp + Autofac.Integration.Mef + LazyWithMetadataRegistrationSourceResources + + + ResXFileCodeGenerator + StronglyTypedMetadataRegistrationSourceResources.Designer.cs + StronglyTypedMetadataRegistrationSourceResources.Designer.cs + CSharp + Autofac.Integration.Mef + StronglyTypedMetadataRegistrationSourceResources + + + ResXFileCodeGenerator + RegistrationExtensionsResources.Designer.cs + RegistrationExtensionsResources.Designer.cs + CSharp + Autofac.Integration.Mef + RegistrationExtensionsResources + + + ResXFileCodeGenerator + ReflectionExtensionsResources.Designer.cs + Util\ReflectionExtensionsResources.Designer.cs + CSharp + Autofac.Integration.Mef.Util + ReflectionExtensionsResources + diff --git a/src/Autofac.Integration.Mef/ContractBasedServiceResources.Designer.cs b/src/Autofac.Integration.Mef/ContractBasedServiceResources.Designer.cs index 51af383..3f38683 100644 --- a/src/Autofac.Integration.Mef/ContractBasedServiceResources.Designer.cs +++ b/src/Autofac.Integration.Mef/ContractBasedServiceResources.Designer.cs @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -14,12 +13,10 @@ namespace Autofac.Integration.Mef { /// /// A strongly-typed resource class, for looking up localized strings, etc. + /// This class was generated by MSBuild using the GenerateResource task. + /// To add or remove a member, edit your .resx file then rerun MSBuild. /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class ContractBasedServiceResources { diff --git a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSourceResources.Designer.cs b/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSourceResources.Designer.cs index cad4461..3989646 100644 --- a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSourceResources.Designer.cs +++ b/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSourceResources.Designer.cs @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -14,12 +13,10 @@ namespace Autofac.Integration.Mef { /// /// A strongly-typed resource class, for looking up localized strings, etc. + /// This class was generated by MSBuild using the GenerateResource task. + /// To add or remove a member, edit your .resx file then rerun MSBuild. /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class LazyWithMetadataRegistrationSourceResources { diff --git a/src/Autofac.Integration.Mef/RegistrationExtensionsResources.Designer.cs b/src/Autofac.Integration.Mef/RegistrationExtensionsResources.Designer.cs index f41eaa7..f92d589 100644 --- a/src/Autofac.Integration.Mef/RegistrationExtensionsResources.Designer.cs +++ b/src/Autofac.Integration.Mef/RegistrationExtensionsResources.Designer.cs @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -14,12 +13,10 @@ namespace Autofac.Integration.Mef { /// /// A strongly-typed resource class, for looking up localized strings, etc. + /// This class was generated by MSBuild using the GenerateResource task. + /// To add or remove a member, edit your .resx file then rerun MSBuild. /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class RegistrationExtensionsResources { diff --git a/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSourceResources.Designer.cs b/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSourceResources.Designer.cs index 854f10a..52a66a9 100644 --- a/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSourceResources.Designer.cs +++ b/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSourceResources.Designer.cs @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -14,12 +13,10 @@ namespace Autofac.Integration.Mef { /// /// A strongly-typed resource class, for looking up localized strings, etc. + /// This class was generated by MSBuild using the GenerateResource task. + /// To add or remove a member, edit your .resx file then rerun MSBuild. /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class StronglyTypedMetadataRegistrationSourceResources { diff --git a/src/Autofac.Integration.Mef/Util/ReflectionExtensionsResources.Designer.cs b/src/Autofac.Integration.Mef/Util/ReflectionExtensionsResources.Designer.cs index b7f83f7..fa1506e 100644 --- a/src/Autofac.Integration.Mef/Util/ReflectionExtensionsResources.Designer.cs +++ b/src/Autofac.Integration.Mef/Util/ReflectionExtensionsResources.Designer.cs @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -14,12 +13,10 @@ namespace Autofac.Integration.Mef.Util { /// /// A strongly-typed resource class, for looking up localized strings, etc. + /// This class was generated by MSBuild using the GenerateResource task. + /// To add or remove a member, edit your .resx file then rerun MSBuild. /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class ReflectionExtensionsResources { diff --git a/test/Autofac.Integration.Mef.Test/Autofac.Integration.Mef.Test.csproj b/test/Autofac.Integration.Mef.Test/Autofac.Integration.Mef.Test.csproj index 1618a95..68b0189 100644 --- a/test/Autofac.Integration.Mef.Test/Autofac.Integration.Mef.Test.csproj +++ b/test/Autofac.Integration.Mef.Test/Autofac.Integration.Mef.Test.csproj @@ -1,17 +1,23 @@  - netcoreapp3.1 - $(NoWarn);CS1591;SA1600 + net6.0 + $(NoWarn);CS1591 true ../../Autofac.snk true + true + ../../build/Test.ruleset AllEnabledByDefault - ../../build/Analyzers.ruleset false latest + enable + + + + @@ -27,16 +33,6 @@ - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -45,6 +41,17 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + + + + + + all + runtime; build; native; contentfiles; analyzers + From 32e62fb87327258124ce2ab890bb0a2d98c73126 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 09:40:53 -0700 Subject: [PATCH 05/20] Spelling words. --- .vscode/settings.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9371753..927073a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,12 @@ "autofac", "browsable", "cref", + "inheritdoc", + "langword", + "paramref", + "resx", + "typeparam", + "typeparamref", "xunit" ], "dotnet-test-explorer.testProjectPath": "test/**/*Test.csproj", From cd7b16ffe9ea31a458ecfc048bdfe5ae46006af6 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 09:41:10 -0700 Subject: [PATCH 06/20] Comma in multi-line initializer. --- src/Autofac.Integration.Mef/RegistrationExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Autofac.Integration.Mef/RegistrationExtensions.cs b/src/Autofac.Integration.Mef/RegistrationExtensions.cs index 6655ac2..6ad49ce 100644 --- a/src/Autofac.Integration.Mef/RegistrationExtensions.cs +++ b/src/Autofac.Integration.Mef/RegistrationExtensions.cs @@ -539,7 +539,7 @@ private static IEnumerable ResolveExports(this IComponentContext context new Export( definition.ContractName, metaProperty.GetValue(resolved) as IDictionary, - () => valueProperty.GetValue(resolved)) + () => valueProperty.GetValue(resolved)), }; } From c75eb2718cc43f5a1e67b0382af622689b0aa407 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:19:51 -0700 Subject: [PATCH 07/20] Resolve analysis warnings. - Nullability markup. - Class visibility in tests. - Dispose of disposable items. --- .../ContractBasedService.cs | 3 +- .../ExportConfigurationBuilder.cs | 6 +- .../NullableAttributes.cs | 110 ++++++++++++++++++ .../RegistrationExtensions.cs | 10 +- .../Util/ReflectionExtensions.cs | 2 +- .../Autofac.Integration.Mef.Test.csproj | 1 + .../CircularDependencyRegistrationTests.cs | 10 +- .../DisposalRegistrationTests.cs | 18 +-- .../DynamicTypeExportRegistrationTests.cs | 32 ++--- .../GenericExportRegistrationTests.cs | 18 +-- ...WithMetadataWhenMetadataIsSuppliedTests.cs | 35 ++---- .../LifetimeScenariosTests.cs | 18 +-- .../MetadataRegistrationTests.cs | 26 +++-- .../MultipleExportRegistrationTests.cs | 10 +- .../Properties/AssemblyInfo.cs | 4 + .../SimpleRegistrationTests.cs | 31 ++--- .../TestTypes/MetaAttribute.cs | 5 +- 17 files changed, 225 insertions(+), 114 deletions(-) create mode 100644 src/Autofac.Integration.Mef/NullableAttributes.cs create mode 100644 test/Autofac.Integration.Mef.Test/Properties/AssemblyInfo.cs diff --git a/src/Autofac.Integration.Mef/ContractBasedService.cs b/src/Autofac.Integration.Mef/ContractBasedService.cs index fb9812d..6982d87 100644 --- a/src/Autofac.Integration.Mef/ContractBasedService.cs +++ b/src/Autofac.Integration.Mef/ContractBasedService.cs @@ -67,8 +67,7 @@ public override string Description /// /// true if the specified is equal to the current ; otherwise, false. /// - /// The parameter is null. - public override bool Equals(object obj) + public override bool Equals(object? obj) { var that = obj as ContractBasedService; diff --git a/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs b/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs index d877294..7327b18 100644 --- a/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs +++ b/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs @@ -19,7 +19,7 @@ public class ExportConfigurationBuilder /// /// A with the simplified contract name MEF uses when resolving the type. /// - internal string ContractName { get; private set; } + internal string ContractName { get; private set; } = ""; /// /// Gets the registration metadata. @@ -27,7 +27,7 @@ public class ExportConfigurationBuilder /// /// A of the registration metadata. /// - internal IDictionary Metadata { get; } = new Dictionary(); + internal IDictionary Metadata { get; } = new Dictionary(); /// /// Gets the specified export type ID. @@ -36,7 +36,7 @@ public class ExportConfigurationBuilder /// A that holds the type ID as specified in MEF /// attributes. This is generated by MEF services. /// - internal string ExportTypeIdentity { get; private set; } + internal string ExportTypeIdentity { get; private set; } = ""; /// /// Export the component under typed contract . diff --git a/src/Autofac.Integration.Mef/NullableAttributes.cs b/src/Autofac.Integration.Mef/NullableAttributes.cs new file mode 100644 index 0000000..6bd5dcb --- /dev/null +++ b/src/Autofac.Integration.Mef/NullableAttributes.cs @@ -0,0 +1,110 @@ +// Copyright (c) Autofac Project. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#pragma warning disable MA0048 // File name must match type name +#pragma warning disable SA1402 // File may only contain a single type +#pragma warning disable SA1649 // File name should match first type name +#if NETSTANDARD2_0 + +namespace System.Diagnostics.CodeAnalysis; + +/// Specifies that null is allowed as an input even if the corresponding type disallows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +internal sealed class AllowNullAttribute : Attribute +{ +} + +/// Specifies that null is disallowed as an input even if the corresponding type allows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +internal sealed class DisallowNullAttribute : Attribute +{ +} + +/// Specifies that an output may be null even if the corresponding type disallows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +internal sealed class MaybeNullAttribute : Attribute +{ +} + +/// Specifies that an output will not be null even if the corresponding type allows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +internal sealed class NotNullAttribute : Attribute +{ +} + +/// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. +[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +internal sealed class MaybeNullWhenAttribute : Attribute +{ + /// + /// Initializes a new instance of the class with the specified return value condition. + /// + /// + /// The return value condition. If the method returns this value, the associated parameter may be null. + /// + public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// + /// Gets a value indicating whether the return value is required to be true or false. + /// + public bool ReturnValue { get; } +} + +/// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. +[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +internal sealed class NotNullWhenAttribute : Attribute +{ + /// + /// Initializes a new instance of the class with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// + /// Gets a value indicating whether the return value is required to be true or false. + /// + public bool ReturnValue { get; } +} + +/// Specifies that the output will be non-null if the named parameter is non-null. +[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] +internal sealed class NotNullIfNotNullAttribute : Attribute +{ + /// + /// Initializes a new instance of the class with the associated parameter name. + /// + /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. + /// + public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; + + /// + /// Gets the name of the parameter. + /// + public string ParameterName { get; } +} + +/// Applied to a method that will never return under any circumstance. +[AttributeUsage(AttributeTargets.Method, Inherited = false)] +internal sealed class DoesNotReturnAttribute : Attribute +{ +} + +/// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. +[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +internal sealed class DoesNotReturnIfAttribute : Attribute +{ + /// + /// Initializes a new instance of the class with the specified parameter value. + /// + /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to + /// the associated parameter matches this value. + /// + public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; + + /// + /// Gets a value indicating whether the parameter value is expected to be true or false. + /// + public bool ParameterValue { get; } +} +#endif diff --git a/src/Autofac.Integration.Mef/RegistrationExtensions.cs b/src/Autofac.Integration.Mef/RegistrationExtensions.cs index 6ad49ce..35cadae 100644 --- a/src/Autofac.Integration.Mef/RegistrationExtensions.cs +++ b/src/Autofac.Integration.Mef/RegistrationExtensions.cs @@ -298,7 +298,7 @@ private static void AttachExport(IComponentRegistryBuilder registry, IComponentR }) .As(contractService) .ExternallyOwned() - .WithMetadata((IEnumerable>)exportConfiguration.Metadata); + .WithMetadata(exportConfiguration.Metadata); registry.Register(rb.CreateRegistration()); } @@ -310,7 +310,7 @@ private static IEnumerable ComponentsForContract(this IComp .ServiceRegistrationsFor(contractService) .Where(cpt => !definition.RequiredMetadata - .Except(cpt.Metadata.Select(m => new KeyValuePair(m.Key, m.Value.GetType()))) + .Except(cpt.Metadata.Select(m => new KeyValuePair(m.Key, m.Value!.GetType()))) .Any()) .ToList(); @@ -332,7 +332,7 @@ private static IRegistrationBuilder DefaultExposedServicesMapper(ExportDefinition ed) { - if (TryMapService(ed, out Service service)) + if (TryMapService(ed, out Service? service)) { yield return service; } @@ -428,7 +428,7 @@ private static void ProcessExportDefinition(ContainerBuilder builder, FuncParameter to the property setter. /// The property info on which the setter is specified. /// True if the parameter is a property setter. - public static bool TryGetDeclaringProperty(this ParameterInfo pi, out PropertyInfo prop) + public static bool TryGetDeclaringProperty(this ParameterInfo pi, [NotNullWhen(true)] out PropertyInfo? prop) { var mi = pi.Member as MethodInfo; if (mi != null && mi.IsSpecialName && mi.Name.StartsWith("set_", StringComparison.Ordinal) && mi.DeclaringType != null) diff --git a/test/Autofac.Integration.Mef.Test/Autofac.Integration.Mef.Test.csproj b/test/Autofac.Integration.Mef.Test/Autofac.Integration.Mef.Test.csproj index 68b0189..71ab788 100644 --- a/test/Autofac.Integration.Mef.Test/Autofac.Integration.Mef.Test.csproj +++ b/test/Autofac.Integration.Mef.Test/Autofac.Integration.Mef.Test.csproj @@ -15,6 +15,7 @@ + diff --git a/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs index b0c3634..865ca13 100644 --- a/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs @@ -34,7 +34,7 @@ public void HandlesLazyMefNonPrerequisiteCircularity2() private static IContainer RegisterTypeCatalogContaining(params Type[] types) { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(types); + using var catalog = new TypeCatalog(types); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); return container; @@ -63,7 +63,7 @@ public void HandlesEagerMefNonPrerequisiteCircularity2() } [Export] - public class LazyCircularA + private class LazyCircularA { [ImportingConstructor] public LazyCircularA(Lazy b) @@ -75,7 +75,7 @@ public LazyCircularA(Lazy b) } [Export] - public class LazyCircularB + private class LazyCircularB { [Import] public Lazy A { get; set; } @@ -86,14 +86,14 @@ public class LazyCircularB * exception. */ [Export] - public class EagerCircularA + private class EagerCircularA { [Import] public EagerCircularB B { get; private set; } } [Export] - public class EagerCircularB + private class EagerCircularB { [Import] public EagerCircularA A { get; set; } diff --git a/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs index 1094c59..bd4e1c2 100644 --- a/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs @@ -15,7 +15,7 @@ public class DisposalRegistrationTests public void DefaultLifetimeForMefComponentsIsSingleton() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(HasDefaultCreationPolicy)); + using var catalog = new TypeCatalog(typeof(HasDefaultCreationPolicy)); builder.RegisterComposablePartCatalog(catalog); AssertDisposalTrackerIsSingleton(builder); } @@ -24,7 +24,7 @@ public void DefaultLifetimeForMefComponentsIsSingleton() public void RespectsSharedCreationPolicy() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(HasSharedCreationPolicy)); + using var catalog = new TypeCatalog(typeof(HasSharedCreationPolicy)); builder.RegisterComposablePartCatalog(catalog); AssertDisposalTrackerIsSingleton(builder); } @@ -33,7 +33,7 @@ public void RespectsSharedCreationPolicy() public void AnyCreationPolicyDefaultsToShared() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(HasAnyCreationPolicy)); + using var catalog = new TypeCatalog(typeof(HasAnyCreationPolicy)); builder.RegisterComposablePartCatalog(catalog); AssertDisposalTrackerIsSingleton(builder); } @@ -53,7 +53,7 @@ private static void AssertDisposalTrackerIsSingleton(ContainerBuilder builder) public void RespectsNonSharedCreationPolicy() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(HasNonSharedCreationPolicy)); + using var catalog = new TypeCatalog(typeof(HasNonSharedCreationPolicy)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); var instance1 = container.Resolve(); @@ -67,7 +67,7 @@ public void RespectsNonSharedCreationPolicy() Assert.True(instance2.IsDisposedPublic); } - public class DisposalTracker : Disposable + private class DisposalTracker : Disposable { public bool IsDisposedPublic { @@ -79,25 +79,25 @@ public bool IsDisposedPublic } [Export(typeof(DisposalTracker))] - public class HasDefaultCreationPolicy : DisposalTracker + private class HasDefaultCreationPolicy : DisposalTracker { } [PartCreationPolicy(CreationPolicy.Any)] [Export(typeof(DisposalTracker))] - public class HasAnyCreationPolicy : DisposalTracker + private class HasAnyCreationPolicy : DisposalTracker { } [PartCreationPolicy(CreationPolicy.Shared)] [Export(typeof(DisposalTracker))] - public class HasSharedCreationPolicy : DisposalTracker + private class HasSharedCreationPolicy : DisposalTracker { } [PartCreationPolicy(CreationPolicy.NonShared)] [Export(typeof(DisposalTracker))] - public class HasNonSharedCreationPolicy : DisposalTracker + private class HasNonSharedCreationPolicy : DisposalTracker { } } diff --git a/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs index 2cd2320..e054bb1 100644 --- a/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs @@ -19,7 +19,7 @@ public class DynamicTypeExportRegistrationTests public void ImportManyFromAutofacExports() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(ImportManyDependency)); + using var catalog = new TypeCatalog(typeof(ImportManyDependency)); builder.RegisterComposablePartCatalog(catalog); foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => typeof(IAutofacDependency).IsAssignableFrom(type) && !type.IsInterface)) @@ -36,7 +36,7 @@ public void ImportManyFromAutofacExports() public void ImportWithMetadataFromAutofacExports() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(ImportWithMetadataDependency)); + using var catalog = new TypeCatalog(typeof(ImportWithMetadataDependency)); builder.RegisterComposablePartCatalog(catalog); const int metaInt = 10; foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => @@ -72,7 +72,7 @@ public void RestrictsExportsBasedOnValueType() public void DuplicateConstructorDependencyImportUsingAttribute() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(ImportsDuplicateAutofacDependency)); + using var catalog = new TypeCatalog(typeof(ImportsDuplicateAutofacDependency)); builder.RegisterComposablePartCatalog(catalog); foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) @@ -90,7 +90,7 @@ public void DuplicateConstructorDependencyImportUsingAttribute() public void DuplicateConstructorDependencyImportUsingInterface() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(ImportsDuplicateAutofacDependency)); + using var catalog = new TypeCatalog(typeof(ImportsDuplicateAutofacDependency)); builder.RegisterComposablePartCatalog(catalog); foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => typeof(IAutofacDependency).IsAssignableFrom(type) && !type.IsInterface)) @@ -108,7 +108,7 @@ public void DuplicateConstructorDependencyImportUsingInterface() public void MixedDependencyConstructorDependencyImport() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(ImportsMixedAutofacMefDependency), typeof(MefDependency)); + using var catalog = new TypeCatalog(typeof(ImportsMixedAutofacMefDependency), typeof(MefDependency)); builder.RegisterComposablePartCatalog(catalog); foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) @@ -122,45 +122,47 @@ public void MixedDependencyConstructorDependencyImport() Assert.NotNull(resolved.Second); } - public interface IAutofacDependency + private interface IAutofacDependency { } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] [ExportFromAutofac] - public class ExportFromAutofacDependencyA : IAutofacDependency + private class ExportFromAutofacDependencyA : IAutofacDependency { } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] [ExportFromAutofac] - public class ExportFromAutofacDependencyB : IAutofacDependency + private class ExportFromAutofacDependencyB : IAutofacDependency { } - public interface IDependency + private interface IDependency { } [Export(typeof(IDependency))] - public class MefDependency : IDependency + private class MefDependency : IDependency { } [Export] - public class ImportManyDependency + private class ImportManyDependency { [ImportMany] public IEnumerable Dependencies { get; set; } } [Export] - public class ImportWithMetadataDependency + private class ImportWithMetadataDependency { [Import] public Lazy Dependency { get; set; } } [Export] - public class ImportsDuplicateAutofacDependency + private class ImportsDuplicateAutofacDependency { public ExportFromAutofacDependencyA First { get; } @@ -175,7 +177,7 @@ public ImportsDuplicateAutofacDependency(ExportFromAutofacDependencyA first, Exp } [Export] - public class ImportsMixedAutofacMefDependency + private class ImportsMixedAutofacMefDependency { public ExportFromAutofacDependencyA First { get; } @@ -190,7 +192,7 @@ public ImportsMixedAutofacMefDependency(ExportFromAutofacDependencyA first, IDep } [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] - public sealed class ExportFromAutofacAttribute : Attribute + private sealed class ExportFromAutofacAttribute : Attribute { } } diff --git a/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs index 10ecf0e..0badd0d 100644 --- a/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs @@ -32,33 +32,35 @@ public void RegisterComposablePartCatalog_OpenGeneric() private static IContainer RegisterTypeCatalogContaining(params Type[] types) { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(types); + using var catalog = new TypeCatalog(types); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); return container; } [InheritedExport] - public interface ITest + private interface ITest { } - public interface IT1 + private interface IT1 { } - public class Test : ITest + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class Test : ITest { } - public class TestConsumer + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class TestConsumer { [Import] public ITest Property { get; set; } } [Export(typeof(OpenGenericExport<>))] - public class OpenGenericExport + private class OpenGenericExport { [ImportingConstructor] public OpenGenericExport(T t) @@ -67,12 +69,12 @@ public OpenGenericExport(T t) } [Export] - public class SimpleType + private class SimpleType { } [Export] - public class OpenGenericConsumer + private class OpenGenericConsumer { [ImportingConstructor] public OpenGenericConsumer(OpenGenericExport o) diff --git a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs index a41091d..7d7749f 100644 --- a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs @@ -6,6 +6,8 @@ using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Linq; +using System.Reflection; +using Autofac.Core; using Autofac.Integration.Mef.Test.TestTypes; using Xunit; @@ -23,11 +25,12 @@ public LazyWithMetadataWhenMetadataIsSuppliedTests() builder.RegisterMetadataRegistrationSources(); builder.RegisterType().WithMetadata("TheInt", SuppliedValue); - var catalog = new TypeCatalog(typeof(ThrowingService), typeof(ServiceConsumer), typeof(NotThrowingService), typeof(SingleServiceConsumer), typeof(ServiceConsumerFromParameters)); + using var catalog = new TypeCatalog(typeof(ThrowingService), typeof(ServiceConsumer), typeof(NotThrowingService), typeof(SingleServiceConsumer), typeof(ServiceConsumerFromParameters)); builder.RegisterComposablePartCatalog(catalog); _container = builder.Build(); } + [SuppressMessage("CA1034", "CA1034", Justification = "Metadata classes must be public for MEF.")] public interface INameMetadata { string Name { get; } @@ -46,18 +49,8 @@ public void InstanceShouldNotBeCreated() var service = serviceConsumer.Services?.FirstOrDefault(x => x.Metadata.Name == "will-throw-on-ctor"); Assert.NotNull(service); Assert.False(service.IsValueCreated); - bool threwError; - try - { - threwError = service.Value == null; - } - catch (Exception ex) - { - threwError = true; - Assert.Contains("This service should never be created", ex.ToString(), StringComparison.OrdinalIgnoreCase); - } - - Assert.True(threwError); + var ex = Assert.Throws(() => { _ = service.Value; }); + Assert.Contains("This service should never be created", ex.ToString(), StringComparison.OrdinalIgnoreCase); } [Fact] @@ -69,18 +62,8 @@ public void InstanceShouldNotBeCreatedAsParameters() var service = serviceConsumer.Services?.FirstOrDefault(x => x.Metadata.Name == "will-throw-on-ctor"); Assert.NotNull(service); Assert.False(service.IsValueCreated); - bool threwError; - try - { - threwError = service.Value == null; - } - catch (Exception ex) - { - threwError = true; - Assert.Contains("This service should never be created", ex.ToString(), StringComparison.OrdinalIgnoreCase); - } - - Assert.True(threwError); + var ex = Assert.Throws(() => { _ = service.Value; }); + Assert.Contains("This service should never be created", ex.ToString(), StringComparison.OrdinalIgnoreCase); } [Fact] @@ -161,7 +144,7 @@ internal class ThrowingService : IService { public ThrowingService() { - throw new Exception("This service should never be created"); + throw new InvalidOperationException("This service should never be created"); } } diff --git a/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs b/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs index 0288530..e73a1ab 100644 --- a/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs +++ b/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs @@ -20,7 +20,7 @@ public void ClassRegisteredInAutofacAsFactoryScopedIsResolvedByMefAsFactoryScope { var containerBuilder = new ContainerBuilder(); - var newAssemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); + using var newAssemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); containerBuilder.RegisterComposablePartCatalog(newAssemblyCatalog); containerBuilder.RegisterType(); containerBuilder.RegisterType() @@ -86,21 +86,24 @@ public void StronglyTypedMetadataRegistrationSourceDoesNotDuplicateDependencies( } } - public interface IDependency + private interface IDependency { } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] [Meta(1)] - public class Dependency1 : IDependency + private class Dependency1 : IDependency { } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] [Meta(2)] - public class Dependency2 : IDependency + private class Dependency2 : IDependency { } - public class RegisteredInAutofac + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class RegisteredInAutofac { public ExportedToMefAndImportingFromAutofac ImportedFormMef { get; set; } @@ -112,13 +115,14 @@ public RegisteredInAutofac(ExportedToMefAndImportingFromAutofac importedFormMef) [Export] [PartCreationPolicy(CreationPolicy.NonShared)] - public class ExportedToMefAndImportingFromAutofac + private class ExportedToMefAndImportingFromAutofac { [Import] public RegisteredInAutofacAndExported ImportedFormAutofac { get; set; } } - public class RegisteredInAutofacAndExported + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class RegisteredInAutofacAndExported { } } diff --git a/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs index 98156dc..a6efa0e 100644 --- a/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Linq; @@ -75,7 +76,7 @@ public void WithMetadata_InterfaceBasedMetadata_SupportMeta() public void ExcludesExportsWithoutRequiredMetadata() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(RequiresMetadataAllowsDefault), typeof(HasNoMetadata)); + using var catalog = new TypeCatalog(typeof(RequiresMetadataAllowsDefault), typeof(HasNoMetadata)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); var rm = container.Resolve(); @@ -87,7 +88,7 @@ public void IncludesExportsWithRequiredMetadata() { var builder = new ContainerBuilder(); builder.RegisterMetadataRegistrationSources(); - var catalog = new TypeCatalog(typeof(RequiresMetadata), typeof(HasMetadata)); + using var catalog = new TypeCatalog(typeof(RequiresMetadata), typeof(HasMetadata)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); var rm = container.Resolve(); @@ -105,7 +106,7 @@ public void SupportsMetadataOnAutofacExports() }; const string exportedString = "Hello"; builder.RegisterInstance(exportedString).Exported(e => e.As().WithMetadata(metadata)); - var catalog = new TypeCatalog(typeof(RequiresMetadata)); + using var catalog = new TypeCatalog(typeof(RequiresMetadata)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); var rm = container.Resolve(); @@ -117,42 +118,44 @@ public void SupportsMetadataOnAutofacExports() public void SetsMultipleExportsToZeroOrMoreCardinalityImports() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog( + using var catalog = new TypeCatalog( typeof(ImportsMany), typeof(HasMetadata), typeof(HasNoMetadata)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); var rm = container.Resolve(); Assert.NotNull(rm.Dependencies); - Assert.Equal(2, rm.Dependencies.Count()); + Assert.Equal(2, rm.Dependencies.Count); } + [SuppressMessage("CA1034", "CA1034", Justification = "Metadata classes must be public for MEF.")] public interface IRequiredMetadata { string Key { get; } } [Export] - public class RequiresMetadata + private class RequiresMetadata { [Import] public Lazy Dependency { get; set; } } [Export] - public class RequiresMetadataAllowsDefault + private class RequiresMetadataAllowsDefault { [Import(AllowDefault = true)] public Lazy Dependency { get; set; } } [Export] - public class ImportsMany + private class ImportsMany { [ImportMany] - public List Dependencies { get; set; } + public Collection Dependencies { get; private set; } } - public class HasNoMetadata + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class HasNoMetadata { [Export] public string Service @@ -164,7 +167,8 @@ public string Service } } - public class HasMetadata + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class HasMetadata { [Export] [ExportMetadata("Key", "Foo")] diff --git a/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs index a185677..0efe782 100644 --- a/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs @@ -17,7 +17,7 @@ public class MultipleExportRegistrationTests public void ImportsEmptyCollectionIfDependencyMissing() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(ImportsMany)); + using var catalog = new TypeCatalog(typeof(ImportsMany)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); var im = container.Resolve(); @@ -29,7 +29,7 @@ public void ImportsEmptyCollectionIfDependencyMissing() public void RespectsExplicitInterchangeServices() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(HasMultipleExports)); + using var catalog = new TypeCatalog(typeof(HasMultipleExports)); var interchangeService1 = new TypedService(typeof(HasMultipleExportsBase)); var interchangeService2 = new KeyedService("b", typeof(HasMultipleExports)); @@ -49,7 +49,7 @@ public void RespectsExplicitInterchangeServices() Assert.False(container.IsRegisteredService(nonInterchangeService2)); } - public class HasMultipleExportsBase + private class HasMultipleExportsBase { } @@ -57,12 +57,12 @@ public class HasMultipleExportsBase [Export("b")] [Export(typeof(HasMultipleExportsBase))] [Export(typeof(HasMultipleExports))] - public class HasMultipleExports : HasMultipleExportsBase + private class HasMultipleExports : HasMultipleExportsBase { } [Export] - public class ImportsMany + private class ImportsMany { [ImportMany] public List Dependencies { get; set; } diff --git a/test/Autofac.Integration.Mef.Test/Properties/AssemblyInfo.cs b/test/Autofac.Integration.Mef.Test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2dec648 --- /dev/null +++ b/test/Autofac.Integration.Mef.Test/Properties/AssemblyInfo.cs @@ -0,0 +1,4 @@ +// Copyright (c) Autofac Project. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +[assembly: CLSCompliant(false)] diff --git a/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs index f721c2e..ca86d53 100644 --- a/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs @@ -16,7 +16,7 @@ public class SimpleRegistrationTests public void MissingDependencyDetected() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(HasMissingDependency)); + using var catalog = new TypeCatalog(typeof(HasMissingDependency)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); Assert.Throws(() => container.Resolve()); @@ -26,7 +26,7 @@ public void MissingDependencyDetected() public void RetrievesExportedInterfaceFromCatalogPart() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(MefDependency)); + using var catalog = new TypeCatalog(typeof(MefDependency)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); var foo = container.Resolve(); @@ -37,7 +37,7 @@ public void RetrievesExportedInterfaceFromCatalogPart() public void SatisfiesImportOnMefComponentFromAutofac() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(ImportsMefDependency)); + using var catalog = new TypeCatalog(typeof(ImportsMefDependency)); builder.RegisterComposablePartCatalog(catalog); builder.RegisterType().Exported(e => e.As()); var container = builder.Build(); @@ -49,7 +49,7 @@ public void SatisfiesImportOnMefComponentFromAutofac() public void SatisfiesImportOnMefComponentFromMef() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(MefDependency), typeof(ImportsMefDependency)); + using var catalog = new TypeCatalog(typeof(MefDependency), typeof(ImportsMefDependency)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); var bar = container.Resolve(); @@ -60,7 +60,7 @@ public void SatisfiesImportOnMefComponentFromMef() public void ResolvesExportsFromContext() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(MefDependency)); + using var catalog = new TypeCatalog(typeof(MefDependency)); builder.RegisterComposablePartCatalog(catalog); builder.RegisterType().Exported(e => e.As()); var container = builder.Build(); @@ -84,7 +84,7 @@ public void RestrictsExportsBasedOnValueType() public void ObjectExportsSupportedByName() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(ObjectExportDerivedClass), typeof(ObjectExportImporter)); + using var catalog = new TypeCatalog(typeof(ObjectExportDerivedClass), typeof(ObjectExportImporter)); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); var importer = container.Resolve(); @@ -95,7 +95,7 @@ public void ObjectExportsSupportedByName() public void DuplicateConstructorDependency() { var builder = new ContainerBuilder(); - var catalog = new TypeCatalog(typeof(MefDependency), typeof(ImportsMefDependency)); + using var catalog = new TypeCatalog(typeof(MefDependency), typeof(ImportsMefDependency)); builder.RegisterType(); builder.RegisterComposablePartCatalog(catalog); var container = builder.Build(); @@ -104,17 +104,17 @@ public void DuplicateConstructorDependency() Assert.NotNull(resolved.Second); } - public interface IDependency + private interface IDependency { } [Export(typeof(IDependency))] - public class MefDependency : IDependency + private class MefDependency : IDependency { } [Export] - public class ImportsMefDependency + private class ImportsMefDependency { [ImportingConstructor] public ImportsMefDependency(IDependency dependency) @@ -126,29 +126,30 @@ public ImportsMefDependency(IDependency dependency) } [Export] - public class HasMissingDependency + private class HasMissingDependency { [Import] public string Dependency { get; set; } } - public class ObjectExportBaseClass + private class ObjectExportBaseClass { } [Export("contract-name", typeof(object))] - public class ObjectExportDerivedClass : ObjectExportBaseClass + private class ObjectExportDerivedClass : ObjectExportBaseClass { } [Export] - public class ObjectExportImporter + private class ObjectExportImporter { [Import("contract-name")] public object Item { get; set; } } - public class ImportsDuplicateMefClass + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class ImportsDuplicateMefClass { public ImportsMefDependency First { get; set; } diff --git a/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs b/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs index ad6e214..dfd241f 100644 --- a/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs +++ b/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs @@ -7,9 +7,10 @@ namespace Autofac.Integration.Mef.Test.TestTypes { [MetadataAttribute] - public class MetaAttribute : Attribute, IMeta + [AttributeUsage(AttributeTargets.Class)] + public sealed class MetaAttribute : Attribute, IMeta { - public MetaAttribute(int value) => TheInt = value; + public MetaAttribute(int theInt) => TheInt = theInt; public int TheInt { get; private set; } } From 5b363d69d6d54fdc0efe6dda9f406536ad845ded Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:26:14 -0700 Subject: [PATCH 08/20] Remove unused usings. --- src/Autofac.Integration.Mef/ContractBasedService.cs | 1 - src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs | 2 -- src/Autofac.Integration.Mef/IMetadataConfiguration.cs | 2 -- .../LazyWithMetadataRegistrationSource.cs | 4 ---- src/Autofac.Integration.Mef/RegistrationExtensions.cs | 6 ------ .../StronglyTypedMetadataRegistrationSource.cs | 4 ---- src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs | 1 - src/Autofac.Integration.Mef/Util/TypeExtensions.cs | 1 - .../CircularDependencyRegistrationTests.cs | 3 --- .../DisposalRegistrationTests.cs | 2 -- .../DynamicTypeExportRegistrationTests.cs | 5 ----- .../GenericExportRegistrationTests.cs | 2 -- .../LazyWithMetadataWhenMetadataIsSuppliedTests.cs | 5 ----- ...LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests.cs | 2 -- test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs | 4 ---- .../MetadataRegistrationTests.cs | 5 ----- .../MultipleExportRegistrationTests.cs | 4 ---- .../Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs | 3 --- .../StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs | 2 -- ...glyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs | 1 - .../Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs | 1 - 21 files changed, 60 deletions(-) diff --git a/src/Autofac.Integration.Mef/ContractBasedService.cs b/src/Autofac.Integration.Mef/ContractBasedService.cs index 6982d87..1a89c2c 100644 --- a/src/Autofac.Integration.Mef/ContractBasedService.cs +++ b/src/Autofac.Integration.Mef/ContractBasedService.cs @@ -1,7 +1,6 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; using System.Globalization; using Autofac.Core; diff --git a/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs b/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs index 7327b18..acb996e 100644 --- a/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs +++ b/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs @@ -1,8 +1,6 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; -using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; diff --git a/src/Autofac.Integration.Mef/IMetadataConfiguration.cs b/src/Autofac.Integration.Mef/IMetadataConfiguration.cs index 5020ecb..0c2f056 100644 --- a/src/Autofac.Integration.Mef/IMetadataConfiguration.cs +++ b/src/Autofac.Integration.Mef/IMetadataConfiguration.cs @@ -1,8 +1,6 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System.Collections.Generic; - namespace Autofac.Integration.Mef { /// diff --git a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs b/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs index b2e7a8d..a39e841 100644 --- a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs +++ b/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs @@ -1,11 +1,7 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; -using System.Collections.Generic; using System.ComponentModel.Composition; -using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.Reflection; using Autofac.Builder; using Autofac.Core; diff --git a/src/Autofac.Integration.Mef/RegistrationExtensions.cs b/src/Autofac.Integration.Mef/RegistrationExtensions.cs index 35cadae..9e56f67 100644 --- a/src/Autofac.Integration.Mef/RegistrationExtensions.cs +++ b/src/Autofac.Integration.Mef/RegistrationExtensions.cs @@ -1,19 +1,13 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; using System.Collections; -using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.ComponentModel.Composition.Primitives; using System.ComponentModel.Composition.ReflectionModel; -using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Linq; -using System.Linq.Expressions; using System.Reflection; -using System.Security.Cryptography; using Autofac.Builder; using Autofac.Core; using Autofac.Core.Registration; diff --git a/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSource.cs b/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSource.cs index 5c97cbb..018fb31 100644 --- a/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSource.cs +++ b/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSource.cs @@ -1,11 +1,7 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; -using System.Collections.Generic; using System.ComponentModel.Composition; -using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.Reflection; using Autofac.Builder; using Autofac.Core; diff --git a/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs b/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs index 840d666..ee81a21 100644 --- a/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs +++ b/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs @@ -1,7 +1,6 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; using System.Globalization; using System.Linq.Expressions; using System.Reflection; diff --git a/src/Autofac.Integration.Mef/Util/TypeExtensions.cs b/src/Autofac.Integration.Mef/Util/TypeExtensions.cs index f273757..e2d10ae 100644 --- a/src/Autofac.Integration.Mef/Util/TypeExtensions.cs +++ b/src/Autofac.Integration.Mef/Util/TypeExtensions.cs @@ -1,6 +1,5 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; namespace Autofac.Integration.Mef.Util { diff --git a/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs index 865ca13..6ac6cc1 100644 --- a/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs @@ -1,11 +1,8 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -using Autofac.Integration.Mef; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs index bd4e1c2..b5eb8d5 100644 --- a/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs @@ -3,9 +3,7 @@ using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -using Autofac.Integration.Mef; using Autofac.Util; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs index e054bb1..60791f4 100644 --- a/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs @@ -1,15 +1,10 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; -using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -using System.Linq; using System.Reflection; -using Autofac.Core.Registration; using Autofac.Integration.Mef.Test.TestTypes; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs index 0badd0d..6fed668 100644 --- a/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs @@ -1,10 +1,8 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs index 7d7749f..ea7f9df 100644 --- a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs @@ -1,15 +1,10 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; -using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -using System.Linq; using System.Reflection; -using Autofac.Core; using Autofac.Integration.Mef.Test.TestTypes; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests.cs index c7c63ad..6a03680 100644 --- a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests.cs @@ -1,11 +1,9 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; using System.ComponentModel.Composition; using Autofac.Core; using Autofac.Integration.Mef.Test.TestTypes; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs b/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs index e73a1ab..cd0655c 100644 --- a/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs +++ b/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs @@ -1,15 +1,11 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; -using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -using System.Linq; using System.Reflection; using Autofac.Features.Metadata; using Autofac.Integration.Mef.Test.TestTypes; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs index a6efa0e..ab92a0c 100644 --- a/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs @@ -1,16 +1,11 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; -using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -using System.Linq; using Autofac.Features.Metadata; -using Autofac.Integration.Mef; using Autofac.Integration.Mef.Test.TestTypes; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs index 0efe782..aed17d2 100644 --- a/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs @@ -1,13 +1,9 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -using System.Linq; using Autofac.Core; -using Autofac.Integration.Mef; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs index ca86d53..0e99c02 100644 --- a/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs @@ -3,10 +3,7 @@ using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -using System.Linq; using Autofac.Core.Registration; -using Autofac.Integration.Mef; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs index 6a90702..2eed39b 100644 --- a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs @@ -1,10 +1,8 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; using Autofac.Features.Metadata; using Autofac.Integration.Mef.Test.TestTypes; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs index b5c6961..29defaa 100644 --- a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs @@ -5,7 +5,6 @@ using Autofac.Core; using Autofac.Features.Metadata; using Autofac.Integration.Mef.Test.TestTypes; -using Xunit; namespace Autofac.Integration.Mef.Test { diff --git a/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs b/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs index dfd241f..1f20169 100644 --- a/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs +++ b/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs @@ -1,7 +1,6 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -using System; using System.ComponentModel.Composition; namespace Autofac.Integration.Mef.Test.TestTypes From 790e49e7f01ffa8aca91db1f8b92c51a99f4e6db Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:26:30 -0700 Subject: [PATCH 09/20] Mark assembly as not CLS compliant. --- src/Autofac.Integration.Mef/Properties/AssemblyInfo.cs | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/Autofac.Integration.Mef/Properties/AssemblyInfo.cs diff --git a/src/Autofac.Integration.Mef/Properties/AssemblyInfo.cs b/src/Autofac.Integration.Mef/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2dec648 --- /dev/null +++ b/src/Autofac.Integration.Mef/Properties/AssemblyInfo.cs @@ -0,0 +1,4 @@ +// Copyright (c) Autofac Project. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +[assembly: CLSCompliant(false)] From 2137cc22c7373914be6bf7d3204ad58e999c260b Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:26:38 -0700 Subject: [PATCH 10/20] Fix redundant compile warning. --- .../Autofac.Integration.Mef.csproj | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Autofac.Integration.Mef/Autofac.Integration.Mef.csproj b/src/Autofac.Integration.Mef/Autofac.Integration.Mef.csproj index 56d1ec0..d2332d8 100644 --- a/src/Autofac.Integration.Mef/Autofac.Integration.Mef.csproj +++ b/src/Autofac.Integration.Mef/Autofac.Integration.Mef.csproj @@ -64,7 +64,14 @@ - + + ResXFileCodeGenerator ContractBasedServiceResources.Designer.cs From 55e222d88b289465dec967979b7e481849306c21 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:27:36 -0700 Subject: [PATCH 11/20] Use file-scoped namespaces. --- .../ContractBasedService.cs | 133 ++- .../ExportConfigurationBuilder.cs | 205 ++-- .../IMetadataConfiguration.cs | 17 +- .../LazyWithMetadataRegistrationSource.cs | 139 ++- .../RegistrationExtensions.cs | 973 +++++++++--------- ...StronglyTypedMetadataRegistrationSource.cs | 121 ++- .../Util/ReflectionExtensions.cs | 87 +- .../Util/TypeExtensions.cs | 53 +- .../CircularDependencyRegistrationTests.cs | 155 ++- .../DisposalRegistrationTests.cs | 155 ++- .../DynamicTypeExportRegistrationTests.cs | 295 +++--- .../GenericExportRegistrationTests.cs | 119 ++- ...WithMetadataWhenMetadataIsSuppliedTests.cs | 239 +++-- ...taWhenNoMatchingMetadataIsSuppliedTests.cs | 45 +- .../LifetimeScenariosTests.cs | 177 ++-- .../MetadataRegistrationTests.cs | 271 +++-- .../MultipleExportRegistrationTests.cs | 95 +- .../SimpleRegistrationTests.cs | 261 +++-- ...ypedMetadataWhenMetadataIsSuppliedTests.cs | 67 +- ...taWhenNoMatchingMetadataIsSuppliedTests.cs | 45 +- .../TestTypes/IMeta.cs | 9 +- .../TestTypes/IMetaWithDefault.cs | 11 +- .../TestTypes/MetaAttribute.cs | 15 +- 23 files changed, 1832 insertions(+), 1855 deletions(-) diff --git a/src/Autofac.Integration.Mef/ContractBasedService.cs b/src/Autofac.Integration.Mef/ContractBasedService.cs index 1a89c2c..5ecdf8d 100644 --- a/src/Autofac.Integration.Mef/ContractBasedService.cs +++ b/src/Autofac.Integration.Mef/ContractBasedService.cs @@ -4,89 +4,88 @@ using System.Globalization; using Autofac.Core; -namespace Autofac.Integration.Mef +namespace Autofac.Integration.Mef; + +/// +/// Identifies a service by the MEF contract name it supports. +/// +public class ContractBasedService : Service { /// - /// Identifies a service by the MEF contract name it supports. + /// Initializes a new instance of the class. /// - public class ContractBasedService : Service + /// The contract name. + /// Type identity of the objects exported under the contract. + public ContractBasedService(string contractName, string exportTypeIdentity) { - /// - /// Initializes a new instance of the class. - /// - /// The contract name. - /// Type identity of the objects exported under the contract. - public ContractBasedService(string contractName, string exportTypeIdentity) + if (string.IsNullOrEmpty(contractName)) { - if (string.IsNullOrEmpty(contractName)) - { - throw new ArgumentOutOfRangeException(nameof(contractName)); - } + throw new ArgumentOutOfRangeException(nameof(contractName)); + } - if (exportTypeIdentity == null) - { - // Issue 310: System.ComponentModel.Composition.Hosting.ExportProvider.BuildImportDefinition - // has a special clause where it will only build the type identity for an import if the type - // is not System.Object. We need to put that back to handle object export/import. - exportTypeIdentity = "System.Object"; - } + if (exportTypeIdentity == null) + { + // Issue 310: System.ComponentModel.Composition.Hosting.ExportProvider.BuildImportDefinition + // has a special clause where it will only build the type identity for an import if the type + // is not System.Object. We need to put that back to handle object export/import. + exportTypeIdentity = "System.Object"; + } - ExportTypeIdentity = exportTypeIdentity; + ExportTypeIdentity = exportTypeIdentity; - ContractName = contractName; - } + ContractName = contractName; + } - /// - /// Gets the type identity of the objects exported under the contract. - /// - public string ExportTypeIdentity { get; } + /// + /// Gets the type identity of the objects exported under the contract. + /// + public string ExportTypeIdentity { get; } - /// - /// Gets the name of the contract. - /// - /// The name of the contract. - public string ContractName { get; } + /// + /// Gets the name of the contract. + /// + /// The name of the contract. + public string ContractName { get; } - /// - /// Gets a human-readable description of the service. - /// - /// The description. - public override string Description + /// + /// Gets a human-readable description of the service. + /// + /// The description. + public override string Description + { + get { - get - { - return string.Format(CultureInfo.CurrentCulture, ContractBasedServiceResources.DescriptionFormat, ContractName); - } + return string.Format(CultureInfo.CurrentCulture, ContractBasedServiceResources.DescriptionFormat, ContractName); } + } - /// - /// Determines whether the specified is equal to the current . - /// - /// The to compare with the current . - /// - /// true if the specified is equal to the current ; otherwise, false. - /// - public override bool Equals(object? obj) - { - var that = obj as ContractBasedService; - - if (that == null) - { - return false; - } - - return ContractName == that.ContractName && ExportTypeIdentity == that.ExportTypeIdentity; - } + /// + /// Determines whether the specified is equal to the current . + /// + /// The to compare with the current . + /// + /// true if the specified is equal to the current ; otherwise, false. + /// + public override bool Equals(object? obj) + { + var that = obj as ContractBasedService; - /// - /// Serves as a hash function for a particular ExportDefinition. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() + if (that == null) { - return ContractName.GetHashCode() ^ ExportTypeIdentity.GetHashCode(); + return false; } + + return ContractName == that.ContractName && ExportTypeIdentity == that.ExportTypeIdentity; + } + + /// + /// Serves as a hash function for a particular ExportDefinition. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return ContractName.GetHashCode() ^ ExportTypeIdentity.GetHashCode(); } } diff --git a/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs b/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs index acb996e..74ce26c 100644 --- a/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs +++ b/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs @@ -4,126 +4,125 @@ using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -namespace Autofac.Integration.Mef +namespace Autofac.Integration.Mef; + +/// +/// Configures an Export on an Autofac component. +/// +public class ExportConfigurationBuilder { /// - /// Configures an Export on an Autofac component. + /// Gets the MEF contract name for the service. + /// + /// + /// A with the simplified contract name MEF uses when resolving the type. + /// + internal string ContractName { get; private set; } = ""; + + /// + /// Gets the registration metadata. + /// + /// + /// A of the registration metadata. + /// + internal IDictionary Metadata { get; } = new Dictionary(); + + /// + /// Gets the specified export type ID. + /// + /// + /// A that holds the type ID as specified in MEF + /// attributes. This is generated by MEF services. + /// + internal string ExportTypeIdentity { get; private set; } = ""; + + /// + /// Export the component under typed contract . /// - public class ExportConfigurationBuilder + /// Contract type. + /// Builder for additional configuration. + public ExportConfigurationBuilder As() { - /// - /// Gets the MEF contract name for the service. - /// - /// - /// A with the simplified contract name MEF uses when resolving the type. - /// - internal string ContractName { get; private set; } = ""; + WithMetadata(CompositionConstants.ExportTypeIdentityMetadataName, AttributedModelServices.GetTypeIdentity(typeof(TContract))); + ContractName = AttributedModelServices.GetContractName(typeof(TContract)); + return this; + } - /// - /// Gets the registration metadata. - /// - /// - /// A of the registration metadata. - /// - internal IDictionary Metadata { get; } = new Dictionary(); + /// + /// Export the component under typed contract . + /// + /// Contract type. + /// Builder for additional configuration. + public ExportConfigurationBuilder As(Type contractType) + { + WithMetadata(CompositionConstants.ExportTypeIdentityMetadataName, AttributedModelServices.GetTypeIdentity(contractType)); + ContractName = AttributedModelServices.GetContractName(contractType); + return this; + } - /// - /// Gets the specified export type ID. - /// - /// - /// A that holds the type ID as specified in MEF - /// attributes. This is generated by MEF services. - /// - internal string ExportTypeIdentity { get; private set; } = ""; + /// + /// Export the component under named contract . + /// + /// Exported value type. + /// Contract name. + /// Builder for additional configuration. + public ExportConfigurationBuilder AsNamed(string name) + { + ContractName = name ?? throw new ArgumentNullException(nameof(name)); + WithMetadata(CompositionConstants.ExportTypeIdentityMetadataName, AttributedModelServices.GetTypeIdentity(typeof(TExportedValue))); + return this; + } - /// - /// Export the component under typed contract . - /// - /// Contract type. - /// Builder for additional configuration. - public ExportConfigurationBuilder As() - { - WithMetadata(CompositionConstants.ExportTypeIdentityMetadataName, AttributedModelServices.GetTypeIdentity(typeof(TContract))); - ContractName = AttributedModelServices.GetContractName(typeof(TContract)); - return this; - } + /// + /// Export the component under named contract . + /// + /// Exported value type. + /// Contract name. + /// Builder for additional configuration. + public ExportConfigurationBuilder AsNamed(Type exportedValueType, string name) + { + ContractName = name ?? throw new ArgumentNullException(nameof(name)); + WithMetadata(CompositionConstants.ExportTypeIdentityMetadataName, AttributedModelServices.GetTypeIdentity(exportedValueType)); + return this; + } - /// - /// Export the component under typed contract . - /// - /// Contract type. - /// Builder for additional configuration. - public ExportConfigurationBuilder As(Type contractType) + /// + /// Add metadata to the export. + /// + /// Metadata key. + /// Metadata value. + /// Builder for additional configuration. + public ExportConfigurationBuilder WithMetadata(string key, object value) + { + Metadata.Add(key, value); + if (key == CompositionConstants.ExportTypeIdentityMetadataName) { - WithMetadata(CompositionConstants.ExportTypeIdentityMetadataName, AttributedModelServices.GetTypeIdentity(contractType)); - ContractName = AttributedModelServices.GetContractName(contractType); - return this; + ExportTypeIdentity = (string)value ?? throw new ArgumentNullException(nameof(value)); } - /// - /// Export the component under named contract . - /// - /// Exported value type. - /// Contract name. - /// Builder for additional configuration. - public ExportConfigurationBuilder AsNamed(string name) - { - ContractName = name ?? throw new ArgumentNullException(nameof(name)); - WithMetadata(CompositionConstants.ExportTypeIdentityMetadataName, AttributedModelServices.GetTypeIdentity(typeof(TExportedValue))); - return this; - } + return this; + } - /// - /// Export the component under named contract . - /// - /// Exported value type. - /// Contract name. - /// Builder for additional configuration. - public ExportConfigurationBuilder AsNamed(Type exportedValueType, string name) + /// + /// Add metadata to the export. + /// + /// Metadata. + /// Builder for additional configuration. + /// + /// Thrown if is . + /// + public ExportConfigurationBuilder WithMetadata(IEnumerable> metadata) + { + if (metadata == null) { - ContractName = name ?? throw new ArgumentNullException(nameof(name)); - WithMetadata(CompositionConstants.ExportTypeIdentityMetadataName, AttributedModelServices.GetTypeIdentity(exportedValueType)); - return this; + throw new ArgumentNullException(nameof(metadata)); } - /// - /// Add metadata to the export. - /// - /// Metadata key. - /// Metadata value. - /// Builder for additional configuration. - public ExportConfigurationBuilder WithMetadata(string key, object value) + foreach (var m in metadata) { - Metadata.Add(key, value); - if (key == CompositionConstants.ExportTypeIdentityMetadataName) - { - ExportTypeIdentity = (string)value ?? throw new ArgumentNullException(nameof(value)); - } - - return this; + WithMetadata(m.Key, m.Value); } - /// - /// Add metadata to the export. - /// - /// Metadata. - /// Builder for additional configuration. - /// - /// Thrown if is . - /// - public ExportConfigurationBuilder WithMetadata(IEnumerable> metadata) - { - if (metadata == null) - { - throw new ArgumentNullException(nameof(metadata)); - } - - foreach (var m in metadata) - { - WithMetadata(m.Key, m.Value); - } - - return this; - } + return this; } } diff --git a/src/Autofac.Integration.Mef/IMetadataConfiguration.cs b/src/Autofac.Integration.Mef/IMetadataConfiguration.cs index 0c2f056..a710654 100644 --- a/src/Autofac.Integration.Mef/IMetadataConfiguration.cs +++ b/src/Autofac.Integration.Mef/IMetadataConfiguration.cs @@ -1,16 +1,15 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace Autofac.Integration.Mef +namespace Autofac.Integration.Mef; + +/// +/// Implementors are able to provide metadata for a component. +/// +public interface IMetadataConfiguration { /// - /// Implementors are able to provide metadata for a component. + /// Gets the metadata properties and values. /// - public interface IMetadataConfiguration - { - /// - /// Gets the metadata properties and values. - /// - IEnumerable> Properties { get; } - } + IEnumerable> Properties { get; } } diff --git a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs b/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs index a39e841..cb905f0 100644 --- a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs +++ b/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs @@ -7,88 +7,87 @@ using Autofac.Core; using Autofac.Integration.Mef.Util; -namespace Autofac.Integration.Mef +namespace Autofac.Integration.Mef; + +/// +/// Support the +/// types automatically whenever type T is registered with the container. +/// +/// +/// Metadata values come from the component registration's metadata. +/// When a dependency of a lazy type is used, the instantiation of the underlying +/// component will be delayed until the property +/// is first accessed. +/// +internal class LazyWithMetadataRegistrationSource : IRegistrationSource { - /// - /// Support the - /// types automatically whenever type T is registered with the container. - /// - /// - /// Metadata values come from the component registration's metadata. - /// When a dependency of a lazy type is used, the instantiation of the underlying - /// component will be delayed until the property - /// is first accessed. - /// - internal class LazyWithMetadataRegistrationSource : IRegistrationSource - { - private static readonly MethodInfo CreateLazyRegistrationMethod = typeof(LazyWithMetadataRegistrationSource).GetMethod("CreateLazyRegistration", BindingFlags.Static | BindingFlags.NonPublic); + private static readonly MethodInfo CreateLazyRegistrationMethod = typeof(LazyWithMetadataRegistrationSource).GetMethod("CreateLazyRegistration", BindingFlags.Static | BindingFlags.NonPublic); - private delegate IComponentRegistration RegistrationCreator(Service service, ServiceRegistration valueRegistration); + private delegate IComponentRegistration RegistrationCreator(Service service, ServiceRegistration valueRegistration); - /// - public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) + /// + public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) + { + if (registrationAccessor == null) { - if (registrationAccessor == null) - { - throw new ArgumentNullException(nameof(registrationAccessor)); - } - - if (!(service is IServiceWithType swt) || !swt.ServiceType.IsGenericTypeDefinedBy(typeof(Lazy<,>))) - { - return Enumerable.Empty(); - } - - var valueType = swt.ServiceType.GetGenericArguments()[0]; - var metaType = swt.ServiceType.GetGenericArguments()[1]; - var valueService = swt.ChangeType(valueType); - var registrationCreator = (RegistrationCreator)Delegate.CreateDelegate( - typeof(RegistrationCreator), - CreateLazyRegistrationMethod.MakeGenericMethod(valueType, metaType)); - - return registrationAccessor(valueService) - .Select(v => registrationCreator(service, v)); + throw new ArgumentNullException(nameof(registrationAccessor)); } - /// - public bool IsAdapterForIndividualComponents + if (!(service is IServiceWithType swt) || !swt.ServiceType.IsGenericTypeDefinedBy(typeof(Lazy<,>))) { - get - { - return false; - } + return Enumerable.Empty(); } - /// - public override string ToString() + var valueType = swt.ServiceType.GetGenericArguments()[0]; + var metaType = swt.ServiceType.GetGenericArguments()[1]; + var valueService = swt.ChangeType(valueType); + var registrationCreator = (RegistrationCreator)Delegate.CreateDelegate( + typeof(RegistrationCreator), + CreateLazyRegistrationMethod.MakeGenericMethod(valueType, metaType)); + + return registrationAccessor(valueService) + .Select(v => registrationCreator(service, v)); + } + + /// + public bool IsAdapterForIndividualComponents + { + get { - return LazyWithMetadataRegistrationSourceResources.LazyWithMetadataRegistrationSourceDescription; + return false; } + } - /// - /// Lazy registration creator called via reflection by the source - /// to generate a component. - /// - /// The type of service being resolved. - /// The type of metadata object associated with the service. - /// The service for which the component registration is being generated. - /// The registration that should provide the component value. - /// - /// An containing a . - /// - [SuppressMessage("IDE0051", "IDE0051", Justification = "Method is consumed via reflection in static member variable in this class.")] - private static IComponentRegistration CreateLazyRegistration(Service providedService, ServiceRegistration valueRegistration) - { - var rb = RegistrationBuilder.ForDelegate( - (c, p) => - { - var context = c.Resolve(); - return new Lazy( - () => (T)context.ResolveComponent(new ResolveRequest(providedService, valueRegistration, p)), - AttributedModelServices.GetMetadataView(valueRegistration.Registration.Target.Metadata)); - }) - .As(providedService); + /// + public override string ToString() + { + return LazyWithMetadataRegistrationSourceResources.LazyWithMetadataRegistrationSourceDescription; + } - return rb.CreateRegistration(); - } + /// + /// Lazy registration creator called via reflection by the source + /// to generate a component. + /// + /// The type of service being resolved. + /// The type of metadata object associated with the service. + /// The service for which the component registration is being generated. + /// The registration that should provide the component value. + /// + /// An containing a . + /// + [SuppressMessage("IDE0051", "IDE0051", Justification = "Method is consumed via reflection in static member variable in this class.")] + private static IComponentRegistration CreateLazyRegistration(Service providedService, ServiceRegistration valueRegistration) + { + var rb = RegistrationBuilder.ForDelegate( + (c, p) => + { + var context = c.Resolve(); + return new Lazy( + () => (T)context.ResolveComponent(new ResolveRequest(providedService, valueRegistration, p)), + AttributedModelServices.GetMetadataView(valueRegistration.Registration.Target.Metadata)); + }) + .As(providedService); + + return rb.CreateRegistration(); } } diff --git a/src/Autofac.Integration.Mef/RegistrationExtensions.cs b/src/Autofac.Integration.Mef/RegistrationExtensions.cs index 9e56f67..f7b9ff7 100644 --- a/src/Autofac.Integration.Mef/RegistrationExtensions.cs +++ b/src/Autofac.Integration.Mef/RegistrationExtensions.cs @@ -14,607 +14,606 @@ using Autofac.Core.Resolving.Pipeline; using Autofac.Integration.Mef.Util; -namespace Autofac.Integration.Mef +namespace Autofac.Integration.Mef; + +/// +/// Extension methods that add MEF hosting capabilities to the container building classes. +/// +public static class RegistrationExtensions { /// - /// Extension methods that add MEF hosting capabilities to the container building classes. + /// Reference to the internal for System.ComponentModel.Composition.ContractNameServices, + /// which is responsible for mapping types to MEF contract names. /// - public static class RegistrationExtensions - { - /// - /// Reference to the internal for System.ComponentModel.Composition.ContractNameServices, - /// which is responsible for mapping types to MEF contract names. - /// - private static readonly Type ContractNameServices = typeof(ExportAttribute).Assembly.GetType("System.ComponentModel.Composition.ContractNameServices", true); - - /// - /// Reference to the property System.ComponentModel.Composition.ContractNameServices.TypeIdentityCache, - /// which holds the dictionary of to contract name mappings. - /// - private static readonly PropertyInfo TypeIdentityCache = ContractNameServices.GetProperty("TypeIdentityCache", BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.NonPublic); - - /// - /// Expose the registered service to MEF parts as an export. - /// - /// The component being registered. - /// Action on an object that configures the export. - /// A registration allowing registration to continue. - public static IRegistrationBuilder Exported(this IRegistrationBuilder registration, Action configurationAction) - where TSingleRegistrationStyle : SingleRegistrationStyle - { - if (registration == null) - { - throw new ArgumentNullException(nameof(registration)); - } - - if (configurationAction == null) - { - throw new ArgumentNullException(nameof(configurationAction)); - } - - var configuration = new ExportConfigurationBuilder(); - configurationAction(configuration); - registration.OnRegistered(e => AttachExport(e.ComponentRegistryBuilder, e.ComponentRegistration, configuration)); + private static readonly Type ContractNameServices = typeof(ExportAttribute).Assembly.GetType("System.ComponentModel.Composition.ContractNameServices", true); - return registration; - } + /// + /// Reference to the property System.ComponentModel.Composition.ContractNameServices.TypeIdentityCache, + /// which holds the dictionary of to contract name mappings. + /// + private static readonly PropertyInfo TypeIdentityCache = ContractNameServices.GetProperty("TypeIdentityCache", BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.NonPublic); - /// - /// Register a MEF catalog. - /// - /// The container builder. - /// The catalog to register. - /// - /// A simple heuristic/type scanning technique will be used to determine which MEF exports - /// are exposed to other components in the Autofac container. - /// - public static void RegisterComposablePartCatalog(this ContainerBuilder builder, ComposablePartCatalog catalog) + /// + /// Expose the registered service to MEF parts as an export. + /// + /// The component being registered. + /// Action on an object that configures the export. + /// A registration allowing registration to continue. + public static IRegistrationBuilder Exported(this IRegistrationBuilder registration, Action configurationAction) + where TSingleRegistrationStyle : SingleRegistrationStyle + { + if (registration == null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (catalog == null) - { - throw new ArgumentNullException(nameof(catalog)); - } - - RegisterComposablePartCatalog(builder, catalog, DefaultExposedServicesMapper); + throw new ArgumentNullException(nameof(registration)); } - /// - /// Register a MEF catalog. - /// - /// The container builder. - /// The catalog to register. - /// The services that will be exposed to other components in the container. - /// - /// Named and typed services only can be matched in the collection. - /// - public static void RegisterComposablePartCatalog(this ContainerBuilder builder, ComposablePartCatalog catalog, params Service[] interchangeServices) + if (configurationAction == null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (catalog == null) - { - throw new ArgumentNullException(nameof(catalog)); - } + throw new ArgumentNullException(nameof(configurationAction)); + } - if (interchangeServices == null) - { - throw new ArgumentNullException(nameof(interchangeServices)); - } + var configuration = new ExportConfigurationBuilder(); + configurationAction(configuration); + registration.OnRegistered(e => AttachExport(e.ComponentRegistryBuilder, e.ComponentRegistration, configuration)); - RegisterComposablePartCatalog(builder, catalog, ed => - interchangeServices - .OfType() - .Where(s => ed.ContractName == AttributedModelServices.GetContractName(s.ServiceType)) - .Cast() - .Union( - interchangeServices - .OfType() - .Where(s => ed.ContractName == (string)s.ServiceKey))); - } - - /// - /// Register a MEF catalog. - /// - /// The container builder. - /// The catalog to register. - /// A mapping function to transform ExportDefinitions into Services. - public static void RegisterComposablePartCatalog(this ContainerBuilder builder, ComposablePartCatalog catalog, Func> exposedServicesMapper) - { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + return registration; + } - if (catalog == null) - { - throw new ArgumentNullException(nameof(catalog)); - } + /// + /// Register a MEF catalog. + /// + /// The container builder. + /// The catalog to register. + /// + /// A simple heuristic/type scanning technique will be used to determine which MEF exports + /// are exposed to other components in the Autofac container. + /// + public static void RegisterComposablePartCatalog(this ContainerBuilder builder, ComposablePartCatalog catalog) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } - if (exposedServicesMapper == null) - { - throw new ArgumentNullException(nameof(exposedServicesMapper)); - } + if (catalog == null) + { + throw new ArgumentNullException(nameof(catalog)); + } - builder.RegisterInstance(catalog).As(new UniqueService()); + RegisterComposablePartCatalog(builder, catalog, DefaultExposedServicesMapper); + } - foreach (var part in catalog.Parts) - { - RegisterComposablePartDefinition(builder, part, exposedServicesMapper); - } + /// + /// Register a MEF catalog. + /// + /// The container builder. + /// The catalog to register. + /// The services that will be exposed to other components in the container. + /// + /// Named and typed services only can be matched in the collection. + /// + public static void RegisterComposablePartCatalog(this ContainerBuilder builder, ComposablePartCatalog catalog, params Service[] interchangeServices) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); } - /// - /// Register a MEF part definition. - /// - /// The container builder. - /// The part definition to register. - /// A mapping function to transform ExportDefinitions into Services. - public static void RegisterComposablePartDefinition(this ContainerBuilder builder, ComposablePartDefinition partDefinition, Func> exposedServicesMapper) + if (catalog == null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - - if (partDefinition == null) - { - throw new ArgumentNullException(nameof(partDefinition)); - } + throw new ArgumentNullException(nameof(catalog)); + } - if (exposedServicesMapper == null) - { - throw new ArgumentNullException(nameof(exposedServicesMapper)); - } + if (interchangeServices == null) + { + throw new ArgumentNullException(nameof(interchangeServices)); + } - var partId = new UniqueService(); - var partRegistration = CreateBasePartRegistration(builder, partDefinition, partId); - if (IsSharedInstance(partDefinition)) - { - partRegistration.SingleInstance(); - } + RegisterComposablePartCatalog(builder, catalog, ed => + interchangeServices + .OfType() + .Where(s => ed.ContractName == AttributedModelServices.GetContractName(s.ServiceType)) + .Cast() + .Union( + interchangeServices + .OfType() + .Where(s => ed.ContractName == (string)s.ServiceKey))); + } - foreach (var iterExportDef in partDefinition.ExportDefinitions) - { - ProcessExportDefinition(builder, exposedServicesMapper, partId, iterExportDef); - } + /// + /// Register a MEF catalog. + /// + /// The container builder. + /// The catalog to register. + /// A mapping function to transform ExportDefinitions into Services. + public static void RegisterComposablePartCatalog(this ContainerBuilder builder, ComposablePartCatalog catalog, Func> exposedServicesMapper) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); } - /// - /// Register a MEF-attributed type as a component. - /// - /// The container builder. - /// The attributed type to register. - /// - /// A simple heuristic/type scanning technique will be used to determine which MEF exports - /// are exposed to other components in the Autofac container. - /// - public static void RegisterComposablePartType(this ContainerBuilder builder, Type partType) + if (catalog == null) { - RegisterComposablePartType(builder, partType, DefaultExposedServicesMapper); + throw new ArgumentNullException(nameof(catalog)); } - /// - /// Register a MEF-attributed type as a component. - /// - /// The container builder. - /// The attributed type to register. - /// A mapping function to transform ExportDefinitions into Services. - public static void RegisterComposablePartType(this ContainerBuilder builder, Type partType, Func> exposedServicesMapper) + if (exposedServicesMapper == null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + throw new ArgumentNullException(nameof(exposedServicesMapper)); + } - if (partType == null) - { - throw new ArgumentNullException(nameof(partType)); - } + builder.RegisterInstance(catalog).As(new UniqueService()); - if (exposedServicesMapper == null) - { - throw new ArgumentNullException(nameof(exposedServicesMapper)); - } - - RegisterComposablePartDefinition( - builder, - AttributedModelServices.CreatePartDefinition(partType, null, true), - exposedServicesMapper); + foreach (var part in catalog.Parts) + { + RegisterComposablePartDefinition(builder, part, exposedServicesMapper); } + } - /// - /// Registers the and - /// registration sources. - /// - /// The container builder. - public static void RegisterMetadataRegistrationSources(this ContainerBuilder builder) + /// + /// Register a MEF part definition. + /// + /// The container builder. + /// The part definition to register. + /// A mapping function to transform ExportDefinitions into Services. + public static void RegisterComposablePartDefinition(this ContainerBuilder builder, ComposablePartDefinition partDefinition, Func> exposedServicesMapper) + { + if (builder == null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - - builder.RegisterSource(new LazyWithMetadataRegistrationSource()); - builder.RegisterSource(new StronglyTypedMetadataRegistrationSource()); + throw new ArgumentNullException(nameof(builder)); } - /// - /// Locate all of the MEF exports registered as supplying contract type T. - /// - /// The contract type. - /// The context to resolve exports from. - /// A list of exports. - public static IEnumerable ResolveExports(this IComponentContext context) + if (partDefinition == null) { - return context.ResolveExports(AttributedModelServices.GetContractName(typeof(T))); + throw new ArgumentNullException(nameof(partDefinition)); } - /// - /// Locate all of the MEF exports registered as supplying contract type T. - /// - /// The contract name. - /// The context to resolve exports from. - /// A list of exports. - public static IEnumerable ResolveExports(this IComponentContext context, string contractName) + if (exposedServicesMapper == null) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - var service = new ContractBasedService(contractName, AttributedModelServices.GetTypeIdentity(typeof(T))); + throw new ArgumentNullException(nameof(exposedServicesMapper)); + } - return context.ComponentRegistry - .ServiceRegistrationsFor(service) - .Select(cpt => context.ResolveComponent(new ResolveRequest(service, cpt, Enumerable.Empty()))) - .Cast(); + var partId = new UniqueService(); + var partRegistration = CreateBasePartRegistration(builder, partDefinition, partId); + if (IsSharedInstance(partDefinition)) + { + partRegistration.SingleInstance(); } - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The component registry is responsible for disposal of contained registrations.")] - private static void AttachExport(IComponentRegistryBuilder registry, IComponentRegistration registration, ExportConfigurationBuilder exportConfiguration) + foreach (var iterExportDef in partDefinition.ExportDefinitions) { - var contractService = new ContractBasedService(exportConfiguration.ContractName, exportConfiguration.ExportTypeIdentity); + ProcessExportDefinition(builder, exposedServicesMapper, partId, iterExportDef); + } + } - var rb = RegistrationBuilder.ForDelegate((c, p) => - { - var ctx = c.Resolve(); - return new Export( - new ExportDefinition(exportConfiguration.ContractName, exportConfiguration.Metadata), - () => ctx.ResolveComponent(new ResolveRequest(contractService, new ServiceRegistration(ServicePipelines.DefaultServicePipeline, registration), Array.Empty()))); - }) - .As(contractService) - .ExternallyOwned() - .WithMetadata(exportConfiguration.Metadata); - - registry.Register(rb.CreateRegistration()); - } - - private static IEnumerable ComponentsForContract(this IComponentContext context, ContractBasedImportDefinition definition, ContractBasedService contractService) - { - var componentsForContract = context - .ComponentRegistry - .ServiceRegistrationsFor(contractService) - .Where(cpt => - !definition.RequiredMetadata - .Except(cpt.Metadata.Select(m => new KeyValuePair(m.Key, m.Value!.GetType()))) - .Any()) - .ToList(); - - if (definition.Cardinality == ImportCardinality.ExactlyOne && componentsForContract.Count == 0) - { - throw new ComponentNotRegisteredException(contractService); - } + /// + /// Register a MEF-attributed type as a component. + /// + /// The container builder. + /// The attributed type to register. + /// + /// A simple heuristic/type scanning technique will be used to determine which MEF exports + /// are exposed to other components in the Autofac container. + /// + public static void RegisterComposablePartType(this ContainerBuilder builder, Type partType) + { + RegisterComposablePartType(builder, partType, DefaultExposedServicesMapper); + } - return componentsForContract; + /// + /// Register a MEF-attributed type as a component. + /// + /// The container builder. + /// The attributed type to register. + /// A mapping function to transform ExportDefinitions into Services. + public static void RegisterComposablePartType(this ContainerBuilder builder, Type partType, Func> exposedServicesMapper) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); } - private static IRegistrationBuilder CreateBasePartRegistration(ContainerBuilder builder, ComposablePartDefinition partDefinition, UniqueService partId) + if (partType == null) { - return builder.Register(c => partDefinition.CreatePart()) - .OnActivating(e => SetPrerequisiteImports(e.Context, e.Instance)) - .OnActivated(e => SetNonPrerequisiteImports(e.Context, e.Instance)) - .As(partId); + throw new ArgumentNullException(nameof(partType)); } - private static IEnumerable DefaultExposedServicesMapper(ExportDefinition ed) + if (exposedServicesMapper == null) { - if (TryMapService(ed, out Service? service)) - { - yield return service; - } + throw new ArgumentNullException(nameof(exposedServicesMapper)); } - private static Type FindType(string exportTypeIdentity) + RegisterComposablePartDefinition( + builder, + AttributedModelServices.CreatePartDefinition(partType, null, true), + exposedServicesMapper); + } + + /// + /// Registers the and + /// registration sources. + /// + /// The container builder. + public static void RegisterMetadataRegistrationSources(this ContainerBuilder builder) + { + if (builder == null) { - var cache = (Dictionary)TypeIdentityCache.GetValue(null, null); - return cache.FirstOrDefault(kvp => kvp.Value == exportTypeIdentity).Key; + throw new ArgumentNullException(nameof(builder)); } - private static string GetTypeIdentity(ExportDefinition exportDef) + builder.RegisterSource(new LazyWithMetadataRegistrationSource()); + builder.RegisterSource(new StronglyTypedMetadataRegistrationSource()); + } + + /// + /// Locate all of the MEF exports registered as supplying contract type T. + /// + /// The contract type. + /// The context to resolve exports from. + /// A list of exports. + public static IEnumerable ResolveExports(this IComponentContext context) + { + return context.ResolveExports(AttributedModelServices.GetContractName(typeof(T))); + } + + /// + /// Locate all of the MEF exports registered as supplying contract type T. + /// + /// The contract name. + /// The context to resolve exports from. + /// A list of exports. + public static IEnumerable ResolveExports(this IComponentContext context, string contractName) + { + if (context == null) { - if (exportDef.Metadata.TryGetValue(CompositionConstants.ExportTypeIdentityMetadataName, out object typeIdentity)) + throw new ArgumentNullException(nameof(context)); + } + + var service = new ContractBasedService(contractName, AttributedModelServices.GetTypeIdentity(typeof(T))); + + return context.ComponentRegistry + .ServiceRegistrationsFor(service) + .Select(cpt => context.ResolveComponent(new ResolveRequest(service, cpt, Enumerable.Empty()))) + .Cast(); + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The component registry is responsible for disposal of contained registrations.")] + private static void AttachExport(IComponentRegistryBuilder registry, IComponentRegistration registration, ExportConfigurationBuilder exportConfiguration) + { + var contractService = new ContractBasedService(exportConfiguration.ContractName, exportConfiguration.ExportTypeIdentity); + + var rb = RegistrationBuilder.ForDelegate((c, p) => { - return (string)typeIdentity; - } + var ctx = c.Resolve(); + return new Export( + new ExportDefinition(exportConfiguration.ContractName, exportConfiguration.Metadata), + () => ctx.ResolveComponent(new ResolveRequest(contractService, new ServiceRegistration(ServicePipelines.DefaultServicePipeline, registration), Array.Empty()))); + }) + .As(contractService) + .ExternallyOwned() + .WithMetadata(exportConfiguration.Metadata); + + registry.Register(rb.CreateRegistration()); + } - return string.Empty; + private static IEnumerable ComponentsForContract(this IComponentContext context, ContractBasedImportDefinition definition, ContractBasedService contractService) + { + var componentsForContract = context + .ComponentRegistry + .ServiceRegistrationsFor(contractService) + .Where(cpt => + !definition.RequiredMetadata + .Except(cpt.Metadata.Select(m => new KeyValuePair(m.Key, m.Value!.GetType()))) + .Any()) + .ToList(); + + if (definition.Cardinality == ImportCardinality.ExactlyOne && componentsForContract.Count == 0) + { + throw new ComponentNotRegisteredException(contractService); } - private static bool IsSharedInstance(ComposablePartDefinition part) + return componentsForContract; + } + + private static IRegistrationBuilder CreateBasePartRegistration(ContainerBuilder builder, ComposablePartDefinition partDefinition, UniqueService partId) + { + return builder.Register(c => partDefinition.CreatePart()) + .OnActivating(e => SetPrerequisiteImports(e.Context, e.Instance)) + .OnActivated(e => SetNonPrerequisiteImports(e.Context, e.Instance)) + .As(partId); + } + + private static IEnumerable DefaultExposedServicesMapper(ExportDefinition ed) + { + if (TryMapService(ed, out Service? service)) { - return IsSharedInstance(part.Metadata); + yield return service; } + } - private static bool IsSharedInstance(ExportDefinition export) + private static Type FindType(string exportTypeIdentity) + { + var cache = (Dictionary)TypeIdentityCache.GetValue(null, null); + return cache.FirstOrDefault(kvp => kvp.Value == exportTypeIdentity).Key; + } + + private static string GetTypeIdentity(ExportDefinition exportDef) + { + if (exportDef.Metadata.TryGetValue(CompositionConstants.ExportTypeIdentityMetadataName, out object typeIdentity)) { - return IsSharedInstance(export.Metadata); + return (string)typeIdentity; } - private static bool IsSharedInstance(IDictionary metadata) + return string.Empty; + } + + private static bool IsSharedInstance(ComposablePartDefinition part) + { + return IsSharedInstance(part.Metadata); + } + + private static bool IsSharedInstance(ExportDefinition export) + { + return IsSharedInstance(export.Metadata); + } + + private static bool IsSharedInstance(IDictionary metadata) + { + if (metadata != null) { - if (metadata != null) + if (metadata.TryGetValue(CompositionConstants.PartCreationPolicyMetadataName, out object pcp)) { - if (metadata.TryGetValue(CompositionConstants.PartCreationPolicyMetadataName, out object pcp)) + // Here we use the MEF default of Shared, but using the Autofac default may make more sense. + if (pcp != null && (CreationPolicy)pcp == CreationPolicy.NonShared) { - // Here we use the MEF default of Shared, but using the Autofac default may make more sense. - if (pcp != null && (CreationPolicy)pcp == CreationPolicy.NonShared) - { - return false; - } + return false; } } - - return true; } - private static void ProcessExportDefinition(ContainerBuilder builder, Func> exposedServicesMapper, UniqueService partId, ExportDefinition iterExportDef) + return true; + } + + private static void ProcessExportDefinition(ContainerBuilder builder, Func> exposedServicesMapper, UniqueService partId, ExportDefinition iterExportDef) + { + var exportDef = iterExportDef; + var contractService = new ContractBasedService(exportDef.ContractName, GetTypeIdentity(exportDef)); + var exportIsShared = IsSharedInstance(exportDef); + + var exportId = new UniqueService(); + var exportReg = builder.Register(c => + { + var p = (ComposablePart)c.ResolveService(partId); + return new Export(exportDef, () => p.GetExportedValue(exportDef)); + }) + .As(exportId, contractService) + .ExternallyOwned() + .WithMetadata(exportDef.Metadata); + + // Issue #348: When a constructor takes in a duplicate dependency like: + // public ImportsDuplicateMefClass(ImportsMefDependency first, ImportsMefDependency second) + // and each of those dependencies also take in the same thing: + // public ImportsMefDependency(IDependency dependency) + // Then when the export/import process gets run, if the export doesn't have + // the same lifetime scope sharing (per-instance vs. singleton) you + // have trouble because the OnActivating from above in the original part + // registration doesn't run, the chained-in prerequisite imports never get + // populated, and everything fails. Setting the export registrations to be + // the same lifetime scope as the part they correspond to fixes the issue. + if (exportIsShared) { - var exportDef = iterExportDef; - var contractService = new ContractBasedService(exportDef.ContractName, GetTypeIdentity(exportDef)); - var exportIsShared = IsSharedInstance(exportDef); + exportReg.SingleInstance(); + } - var exportId = new UniqueService(); - var exportReg = builder.Register(c => - { - var p = (ComposablePart)c.ResolveService(partId); - return new Export(exportDef, () => p.GetExportedValue(exportDef)); - }) - .As(exportId, contractService) - .ExternallyOwned() - .WithMetadata(exportDef.Metadata); - - // Issue #348: When a constructor takes in a duplicate dependency like: - // public ImportsDuplicateMefClass(ImportsMefDependency first, ImportsMefDependency second) - // and each of those dependencies also take in the same thing: - // public ImportsMefDependency(IDependency dependency) - // Then when the export/import process gets run, if the export doesn't have - // the same lifetime scope sharing (per-instance vs. singleton) you - // have trouble because the OnActivating from above in the original part - // registration doesn't run, the chained-in prerequisite imports never get - // populated, and everything fails. Setting the export registrations to be - // the same lifetime scope as the part they correspond to fixes the issue. - if (exportIsShared) - { - exportReg.SingleInstance(); - } + var additionalServices = exposedServicesMapper(exportDef).ToArray(); - var additionalServices = exposedServicesMapper(exportDef).ToArray(); + if (additionalServices.Length > 0) + { + var additionalRegistration = builder.Register(c => ((Export)c.ResolveService(exportId)).Value) + .As(additionalServices) + .ExternallyOwned() + .WithMetadata(exportDef.Metadata); - if (additionalServices.Length > 0) + if (exportIsShared) { - var additionalRegistration = builder.Register(c => ((Export)c.ResolveService(exportId)).Value) - .As(additionalServices) - .ExternallyOwned() - .WithMetadata(exportDef.Metadata); - - if (exportIsShared) - { - additionalRegistration.SingleInstance(); - } + additionalRegistration.SingleInstance(); } } + } - private static bool TryGetLazyType(this ContractBasedImportDefinition definition, [NotNullWhen(true)] out Type? resultType, [NotNullWhen(true)] out Type? lazyType) + private static bool TryGetLazyType(this ContractBasedImportDefinition definition, [NotNullWhen(true)] out Type? resultType, [NotNullWhen(true)] out Type? lazyType) + { + // There are a couple of classes that are internal that provide us some information we can use to + // properly gauge if we need to do our lazy activation or not. + var definitionType = definition.GetType(); + LazyMemberInfo? lazyMemberInfo = null; + resultType = null; + lazyType = null; + switch (definitionType.Name) { - // There are a couple of classes that are internal that provide us some information we can use to - // properly gauge if we need to do our lazy activation or not. - var definitionType = definition.GetType(); - LazyMemberInfo? lazyMemberInfo = null; - resultType = null; - lazyType = null; - switch (definitionType.Name) - { - // The first case is the base class of the second case for both of these pairs. - case "ReflectionMemberImportDefinition": - case "PartCreatorMemberImportDefinition": - lazyMemberInfo = ReflectionModelServices.GetImportingMember(definition); - break; - case "ReflectionParameterImportDefinition": - case "PartCreatorParameterImportDefinition": - resultType = ReflectionModelServices.GetImportingParameter(definition)?.Value?.ParameterType; - break; - default: - return false; - } + // The first case is the base class of the second case for both of these pairs. + case "ReflectionMemberImportDefinition": + case "PartCreatorMemberImportDefinition": + lazyMemberInfo = ReflectionModelServices.GetImportingMember(definition); + break; + case "ReflectionParameterImportDefinition": + case "PartCreatorParameterImportDefinition": + resultType = ReflectionModelServices.GetImportingParameter(definition)?.Value?.ParameterType; + break; + default: + return false; + } - if (lazyMemberInfo.HasValue) + if (lazyMemberInfo.HasValue) + { + foreach (var accessor in lazyMemberInfo.Value.GetAccessors()) { - foreach (var accessor in lazyMemberInfo.Value.GetAccessors()) + if (accessor is MethodInfo methodInfo) { - if (accessor is MethodInfo methodInfo) - { - // This is either a getter or a setter. - resultType = methodInfo.ReturnType; - if (resultType == typeof(void)) - { - resultType = methodInfo.GetParameters()[0].ParameterType; - } - - break; - } - else if (accessor is FieldInfo fieldInfo) + // This is either a getter or a setter. + resultType = methodInfo.ReturnType; + if (resultType == typeof(void)) { - resultType = fieldInfo.FieldType; - break; + resultType = methodInfo.GetParameters()[0].ParameterType; } - } - } - if (resultType != null) - { - // Have to handle 2 cases - // Single cardinality = Lazy - // Multiple cardinality = IEnumerable> - bool isLazy; - if ( - (isLazy = resultType.IsGenericTypeDefinedBy(typeof(Lazy<,>))) - || - ( - resultType.IsGenericTypeDefinedBy(typeof(IEnumerable<>)) - && - resultType.GetGenericArguments()[0].IsGenericTypeDefinedBy(typeof(Lazy<,>)))) + break; + } + else if (accessor is FieldInfo fieldInfo) { - lazyType = isLazy ? resultType : resultType.GetGenericArguments()[0]; - var objectType = lazyType.GetGenericArguments()[0]; - - // Resolve as Lazy> so we can leverage the Metadata value to populate - // the metadata on the Exports built later. - // If we do not change the type here, we end up losing the name/value pairs so the resulting - // Metadata will not be populated - lazyType = lazyType - .GetGenericTypeDefinition() - .MakeGenericType(objectType, typeof(IDictionary)); - - if (!isLazy) - { - resultType = typeof(IEnumerable<>).MakeGenericType(lazyType); - } - else - { - resultType = lazyType; - } - - return true; + resultType = fieldInfo.FieldType; + break; } } - - resultType = null; - lazyType = null; - return false; } - private static IEnumerable ResolveExports(this IComponentContext context, ContractBasedImportDefinition definition) + if (resultType != null) { - if (definition.TryGetLazyType(out var resultType, out var lazyType) && context.TryResolve(resultType, out var resolved)) - { - var valueProperty = lazyType.GetProperty("Value"); - var metaProperty = lazyType.GetProperty("Metadata"); - if (resolved is IEnumerable enumerable) + // Have to handle 2 cases + // Single cardinality = Lazy + // Multiple cardinality = IEnumerable> + bool isLazy; + if ( + (isLazy = resultType.IsGenericTypeDefinedBy(typeof(Lazy<,>))) + || + ( + resultType.IsGenericTypeDefinedBy(typeof(IEnumerable<>)) + && + resultType.GetGenericArguments()[0].IsGenericTypeDefinedBy(typeof(Lazy<,>)))) + { + lazyType = isLazy ? resultType : resultType.GetGenericArguments()[0]; + var objectType = lazyType.GetGenericArguments()[0]; + + // Resolve as Lazy> so we can leverage the Metadata value to populate + // the metadata on the Exports built later. + // If we do not change the type here, we end up losing the name/value pairs so the resulting + // Metadata will not be populated + lazyType = lazyType + .GetGenericTypeDefinition() + .MakeGenericType(objectType, typeof(IDictionary)); + + if (!isLazy) { - return enumerable - .Cast() - .Select( - r => new Export( - definition.ContractName, - metaProperty.GetValue(r) as IDictionary, - () => valueProperty.GetValue(r))); + resultType = typeof(IEnumerable<>).MakeGenericType(lazyType); } - - return new Export[] + else { - new Export( + resultType = lazyType; + } + + return true; + } + } + + resultType = null; + lazyType = null; + return false; + } + + private static IEnumerable ResolveExports(this IComponentContext context, ContractBasedImportDefinition definition) + { + if (definition.TryGetLazyType(out var resultType, out var lazyType) && context.TryResolve(resultType, out var resolved)) + { + var valueProperty = lazyType.GetProperty("Value"); + var metaProperty = lazyType.GetProperty("Metadata"); + if (resolved is IEnumerable enumerable) + { + return enumerable + .Cast() + .Select( + r => new Export( definition.ContractName, - metaProperty.GetValue(resolved) as IDictionary, - () => valueProperty.GetValue(resolved)), - }; + metaProperty.GetValue(r) as IDictionary, + () => valueProperty.GetValue(r))); } - var contractService = new ContractBasedService(definition.ContractName, definition.RequiredTypeIdentity); + return new Export[] + { + new Export( + definition.ContractName, + metaProperty.GetValue(resolved) as IDictionary, + () => valueProperty.GetValue(resolved)), + }; + } + + var contractService = new ContractBasedService(definition.ContractName, definition.RequiredTypeIdentity); - var componentsForContract = context.ComponentsForContract(definition, contractService); + var componentsForContract = context.ComponentsForContract(definition, contractService); - var exportsForContract = componentsForContract - .Select(cpt => context.ResolveComponent(new ResolveRequest(contractService, cpt, Enumerable.Empty()))) - .Cast() - .ToList(); + var exportsForContract = componentsForContract + .Select(cpt => context.ResolveComponent(new ResolveRequest(contractService, cpt, Enumerable.Empty()))) + .Cast() + .ToList(); - return exportsForContract; - } + return exportsForContract; + } - private static void SetImports(IComponentContext context, ComposablePart composablePart, bool prerequisite) + private static void SetImports(IComponentContext context, ComposablePart composablePart, bool prerequisite) + { + foreach (var import in composablePart + .ImportDefinitions + .Where(id => id.IsPrerequisite == prerequisite)) { - foreach (var import in composablePart - .ImportDefinitions - .Where(id => id.IsPrerequisite == prerequisite)) + if (!(import is ContractBasedImportDefinition definition)) { - if (!(import is ContractBasedImportDefinition definition)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, RegistrationExtensionsResources.ContractBasedOnly, import)); - } - - var exportsForContract = context.ResolveExports(definition); - composablePart.SetImport(import, exportsForContract); + throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, RegistrationExtensionsResources.ContractBasedOnly, import)); } - } - private static void SetNonPrerequisiteImports(IComponentContext context, ComposablePart composablePart) - { - SetImports(context, composablePart, false); - composablePart.Activate(); + var exportsForContract = context.ResolveExports(definition); + composablePart.SetImport(import, exportsForContract); } + } - private static void SetPrerequisiteImports(IComponentContext context, ComposablePart composablePart) + private static void SetNonPrerequisiteImports(IComponentContext context, ComposablePart composablePart) + { + SetImports(context, composablePart, false); + composablePart.Activate(); + } + + private static void SetPrerequisiteImports(IComponentContext context, ComposablePart composablePart) + { + SetImports(context, composablePart, true); + } + + private static bool TryMapService(ExportDefinition ed, [NotNullWhen(true)] out Service? service) + { + /* Issue 326: MEF is string based, not type-based, so when an export and + * an import line up on contract (or type identity) it's always based on a + * generated contract name rather than an actual type. Usually the contract + * name and the type name are the same, just that the contract name is ONLY + * the type name without any assembly qualifier. However, when you get to + * generics, the type name gets mangled a bit. ITest becomes ITest(Foo) + * with parens instead of angle brackets. If you have multiple types with the + * same name but in different assemblies, or nested types, things get even more + * mangled. For this reason, you have to access the internal type-to-contract + * map that MEF uses when building these items at runtime. Unfortunately, that's + * not publicly exposed so we have to use reflection to reverse the lookup. + * + * Note we tried doing something like... + * AppDomain.CurrentDomain.GetAssemblies() + * .SelectMany(asm => asm.GetTypes()) + * .SingleOrDefault(t => AttributedModelServices.GetContractName(t) == exportTypeIdentity) + * + * But that doesn't work because when you enumerate the types in the assemblies + * you only get OPEN generics, and many types expose services that are CLOSED + * generics. That means the lambda above still won't find the service and things + * still won't get registered. */ + var ct = FindType(ed.ContractName); + if (ct != null) { - SetImports(context, composablePart, true); + service = new TypedService(ct); + return true; } - private static bool TryMapService(ExportDefinition ed, [NotNullWhen(true)] out Service? service) + var et = FindType((string)ed.Metadata[CompositionConstants.ExportTypeIdentityMetadataName]); + if (et != null) { - /* Issue 326: MEF is string based, not type-based, so when an export and - * an import line up on contract (or type identity) it's always based on a - * generated contract name rather than an actual type. Usually the contract - * name and the type name are the same, just that the contract name is ONLY - * the type name without any assembly qualifier. However, when you get to - * generics, the type name gets mangled a bit. ITest becomes ITest(Foo) - * with parens instead of angle brackets. If you have multiple types with the - * same name but in different assemblies, or nested types, things get even more - * mangled. For this reason, you have to access the internal type-to-contract - * map that MEF uses when building these items at runtime. Unfortunately, that's - * not publicly exposed so we have to use reflection to reverse the lookup. - * - * Note we tried doing something like... - * AppDomain.CurrentDomain.GetAssemblies() - * .SelectMany(asm => asm.GetTypes()) - * .SingleOrDefault(t => AttributedModelServices.GetContractName(t) == exportTypeIdentity) - * - * But that doesn't work because when you enumerate the types in the assemblies - * you only get OPEN generics, and many types expose services that are CLOSED - * generics. That means the lambda above still won't find the service and things - * still won't get registered. */ - var ct = FindType(ed.ContractName); - if (ct != null) - { - service = new TypedService(ct); - return true; - } - - var et = FindType((string)ed.Metadata[CompositionConstants.ExportTypeIdentityMetadataName]); - if (et != null) - { - service = new KeyedService(ed.ContractName, et); - return true; - } - - service = null; - return false; + service = new KeyedService(ed.ContractName, et); + return true; } + + service = null; + return false; } } diff --git a/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSource.cs b/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSource.cs index 018fb31..957e2ab 100644 --- a/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSource.cs +++ b/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSource.cs @@ -8,79 +8,78 @@ using Autofac.Features.Metadata; using Autofac.Integration.Mef.Util; -namespace Autofac.Integration.Mef +namespace Autofac.Integration.Mef; + +/// +/// Support the +/// types automatically whenever type T is registered with the container. +/// Metadata values come from the component registration's metadata. +/// +internal class StronglyTypedMetadataRegistrationSource : IRegistrationSource { - /// - /// Support the - /// types automatically whenever type T is registered with the container. - /// Metadata values come from the component registration's metadata. - /// - internal class StronglyTypedMetadataRegistrationSource : IRegistrationSource - { - private static readonly MethodInfo CreateMetaRegistrationMethod = typeof(StronglyTypedMetadataRegistrationSource).GetMethod("CreateMetaRegistration", BindingFlags.Static | BindingFlags.NonPublic); + private static readonly MethodInfo CreateMetaRegistrationMethod = typeof(StronglyTypedMetadataRegistrationSource).GetMethod("CreateMetaRegistration", BindingFlags.Static | BindingFlags.NonPublic); - private delegate IComponentRegistration RegistrationCreator(Service service, ServiceRegistration valueRegistration); + private delegate IComponentRegistration RegistrationCreator(Service service, ServiceRegistration valueRegistration); - /// - public bool IsAdapterForIndividualComponents + /// + public bool IsAdapterForIndividualComponents + { + get { - get - { - return false; - } + return false; } + } - /// - public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) + /// + public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) + { + if (registrationAccessor == null) { - if (registrationAccessor == null) - { - throw new ArgumentNullException(nameof(registrationAccessor)); - } - - if (!(service is IServiceWithType swt) || !swt.ServiceType.IsGenericTypeDefinedBy(typeof(Meta<,>))) - { - return Enumerable.Empty(); - } - - var valueType = swt.ServiceType.GetGenericArguments()[0]; - var metaType = swt.ServiceType.GetGenericArguments()[1]; - var valueService = swt.ChangeType(valueType); - var registrationCreator = (RegistrationCreator)Delegate.CreateDelegate( - typeof(RegistrationCreator), - CreateMetaRegistrationMethod.MakeGenericMethod(valueType, metaType)); - - return registrationAccessor(valueService) - .Select(v => registrationCreator.Invoke(service, v)); + throw new ArgumentNullException(nameof(registrationAccessor)); } - /// - public override string ToString() + if (!(service is IServiceWithType swt) || !swt.ServiceType.IsGenericTypeDefinedBy(typeof(Meta<,>))) { - return StronglyTypedMetadataRegistrationSourceResources.StronglyTypedMetaRegistrationSourceDescription; + return Enumerable.Empty(); } - /// - /// Strongly typed registration creator called via reflection by the source - /// to generate a component. - /// - /// The type of service being resolved. - /// The type of metadata object associated with the service. - /// The service for which the component registration is being generated. - /// The registration that should provide the component value. - /// - /// An containing a . - /// - [SuppressMessage("IDE0051", "IDE0051", Justification = "Method is consumed via reflection in static member variable in this class.")] - private static IComponentRegistration CreateMetaRegistration(Service providedService, ServiceRegistration valueRegistration) - { - var rb = RegistrationBuilder - .ForDelegate((c, p) => new Meta( - (T)c.ResolveComponent(new ResolveRequest(providedService, valueRegistration, p)), - AttributedModelServices.GetMetadataView(valueRegistration.Registration.Target.Metadata))) - .As(providedService); + var valueType = swt.ServiceType.GetGenericArguments()[0]; + var metaType = swt.ServiceType.GetGenericArguments()[1]; + var valueService = swt.ChangeType(valueType); + var registrationCreator = (RegistrationCreator)Delegate.CreateDelegate( + typeof(RegistrationCreator), + CreateMetaRegistrationMethod.MakeGenericMethod(valueType, metaType)); - return rb.CreateRegistration(); - } + return registrationAccessor(valueService) + .Select(v => registrationCreator.Invoke(service, v)); + } + + /// + public override string ToString() + { + return StronglyTypedMetadataRegistrationSourceResources.StronglyTypedMetaRegistrationSourceDescription; + } + + /// + /// Strongly typed registration creator called via reflection by the source + /// to generate a component. + /// + /// The type of service being resolved. + /// The type of metadata object associated with the service. + /// The service for which the component registration is being generated. + /// The registration that should provide the component value. + /// + /// An containing a . + /// + [SuppressMessage("IDE0051", "IDE0051", Justification = "Method is consumed via reflection in static member variable in this class.")] + private static IComponentRegistration CreateMetaRegistration(Service providedService, ServiceRegistration valueRegistration) + { + var rb = RegistrationBuilder + .ForDelegate((c, p) => new Meta( + (T)c.ResolveComponent(new ResolveRequest(providedService, valueRegistration, p)), + AttributedModelServices.GetMetadataView(valueRegistration.Registration.Target.Metadata))) + .As(providedService); + + return rb.CreateRegistration(); } } diff --git a/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs b/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs index ee81a21..aee992d 100644 --- a/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs +++ b/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs @@ -5,59 +5,58 @@ using System.Linq.Expressions; using System.Reflection; -namespace Autofac.Integration.Mef.Util +namespace Autofac.Integration.Mef.Util; + +/// +/// Extension methods for reflection-related types. +/// +internal static class ReflectionExtensions { /// - /// Extension methods for reflection-related types. + /// Maps from a property-set-value parameter to the declaring property. /// - internal static class ReflectionExtensions + /// Parameter to the property setter. + /// The property info on which the setter is specified. + /// True if the parameter is a property setter. + public static bool TryGetDeclaringProperty(this ParameterInfo pi, [NotNullWhen(true)] out PropertyInfo? prop) { - /// - /// Maps from a property-set-value parameter to the declaring property. - /// - /// Parameter to the property setter. - /// The property info on which the setter is specified. - /// True if the parameter is a property setter. - public static bool TryGetDeclaringProperty(this ParameterInfo pi, [NotNullWhen(true)] out PropertyInfo? prop) + var mi = pi.Member as MethodInfo; + if (mi != null && mi.IsSpecialName && mi.Name.StartsWith("set_", StringComparison.Ordinal) && mi.DeclaringType != null) { - var mi = pi.Member as MethodInfo; - if (mi != null && mi.IsSpecialName && mi.Name.StartsWith("set_", StringComparison.Ordinal) && mi.DeclaringType != null) - { - prop = mi.DeclaringType.GetProperty(mi.Name.Substring(4)); - return true; - } - - prop = null; - return false; + prop = mi.DeclaringType.GetProperty(mi.Name.Substring(4)); + return true; } - /// - /// Get a PropertyInfo object from an expression of the form - /// x => x.P. - /// - /// Type declaring the property. - /// The type of the property. - /// Expression mapping an instance of the - /// declaring type to the property value. - /// Property info. - public static PropertyInfo GetProperty( - Expression> propertyAccessor) - { - if (propertyAccessor == null) - { - throw new ArgumentNullException(nameof(propertyAccessor)); - } + prop = null; + return false; + } - var mex = propertyAccessor.Body as MemberExpression; - if (!(mex?.Member is PropertyInfo)) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - ReflectionExtensionsResources.ExpressionNotPropertyAccessor, - propertyAccessor)); - } + /// + /// Get a PropertyInfo object from an expression of the form + /// x => x.P. + /// + /// Type declaring the property. + /// The type of the property. + /// Expression mapping an instance of the + /// declaring type to the property value. + /// Property info. + public static PropertyInfo GetProperty( + Expression> propertyAccessor) + { + if (propertyAccessor == null) + { + throw new ArgumentNullException(nameof(propertyAccessor)); + } - return (PropertyInfo)mex.Member; + var mex = propertyAccessor.Body as MemberExpression; + if (!(mex?.Member is PropertyInfo)) + { + throw new ArgumentException(string.Format( + CultureInfo.CurrentCulture, + ReflectionExtensionsResources.ExpressionNotPropertyAccessor, + propertyAccessor)); } + + return (PropertyInfo)mex.Member; } } diff --git a/src/Autofac.Integration.Mef/Util/TypeExtensions.cs b/src/Autofac.Integration.Mef/Util/TypeExtensions.cs index e2d10ae..afc353a 100644 --- a/src/Autofac.Integration.Mef/Util/TypeExtensions.cs +++ b/src/Autofac.Integration.Mef/Util/TypeExtensions.cs @@ -1,39 +1,38 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace Autofac.Integration.Mef.Util +namespace Autofac.Integration.Mef.Util; + +/// +/// Extension methods for working with . +/// +internal static class TypeExtensions { /// - /// Extension methods for working with . + /// Determines if a closed generic is an implementation of a given open generic. /// - internal static class TypeExtensions + /// + /// The closed generic type to check. + /// + /// + /// The open generic type to compare against the closed generic. + /// + /// + /// if is a closed generic version of + /// ; otherwise . + /// + internal static bool IsGenericTypeDefinedBy(this Type @this, Type openGeneric) { - /// - /// Determines if a closed generic is an implementation of a given open generic. - /// - /// - /// The closed generic type to check. - /// - /// - /// The open generic type to compare against the closed generic. - /// - /// - /// if is a closed generic version of - /// ; otherwise . - /// - internal static bool IsGenericTypeDefinedBy(this Type @this, Type openGeneric) + if (@this == null) { - if (@this == null) - { - throw new ArgumentNullException(nameof(@this)); - } - - if (openGeneric == null) - { - throw new ArgumentNullException(nameof(openGeneric)); - } + throw new ArgumentNullException(nameof(@this)); + } - return !@this.ContainsGenericParameters && @this.IsGenericType && @this.GetGenericTypeDefinition() == openGeneric; + if (openGeneric == null) + { + throw new ArgumentNullException(nameof(openGeneric)); } + + return !@this.ContainsGenericParameters && @this.IsGenericType && @this.GetGenericTypeDefinition() == openGeneric; } } diff --git a/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs index 6ac6cc1..5c72466 100644 --- a/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/CircularDependencyRegistrationTests.cs @@ -4,96 +4,95 @@ using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class CircularDependencyRegistrationTests { - public class CircularDependencyRegistrationTests + [Fact] + public void HandlesLazyMefNonPrerequisiteCircularity1() { - [Fact] - public void HandlesLazyMefNonPrerequisiteCircularity1() - { - var container = RegisterTypeCatalogContaining(typeof(LazyCircularA), typeof(LazyCircularB)); - var a = container.Resolve(); - Assert.NotNull(a); - Assert.NotNull(a.B); - Assert.Same(a, a.B.Value.A.Value); - } + var container = RegisterTypeCatalogContaining(typeof(LazyCircularA), typeof(LazyCircularB)); + var a = container.Resolve(); + Assert.NotNull(a); + Assert.NotNull(a.B); + Assert.Same(a, a.B.Value.A.Value); + } - [Fact] - public void HandlesLazyMefNonPrerequisiteCircularity2() - { - var container = RegisterTypeCatalogContaining(typeof(LazyCircularA), typeof(LazyCircularB)); - var b = container.Resolve(); - Assert.NotNull(b); - Assert.NotNull(b.A); - Assert.Same(b, b.A.Value.B.Value); - } + [Fact] + public void HandlesLazyMefNonPrerequisiteCircularity2() + { + var container = RegisterTypeCatalogContaining(typeof(LazyCircularA), typeof(LazyCircularB)); + var b = container.Resolve(); + Assert.NotNull(b); + Assert.NotNull(b.A); + Assert.Same(b, b.A.Value.B.Value); + } - private static IContainer RegisterTypeCatalogContaining(params Type[] types) - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(types); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - return container; - } + private static IContainer RegisterTypeCatalogContaining(params Type[] types) + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(types); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + return container; + } - [Fact] - public void HandlesEagerMefNonPrerequisiteCircularity1() - { - var container = RegisterTypeCatalogContaining(typeof(EagerCircularA), typeof(EagerCircularB)); - var a = container.Resolve(); - Assert.NotNull(a); - Assert.NotNull(a.B); - Assert.Same(a, a.B.A); - Assert.Same(a.B, a.B.A.B); - } + [Fact] + public void HandlesEagerMefNonPrerequisiteCircularity1() + { + var container = RegisterTypeCatalogContaining(typeof(EagerCircularA), typeof(EagerCircularB)); + var a = container.Resolve(); + Assert.NotNull(a); + Assert.NotNull(a.B); + Assert.Same(a, a.B.A); + Assert.Same(a.B, a.B.A.B); + } - [Fact] - public void HandlesEagerMefNonPrerequisiteCircularity2() - { - var container = RegisterTypeCatalogContaining(typeof(EagerCircularA), typeof(EagerCircularB)); - var b = container.Resolve(); - Assert.NotNull(b); - Assert.NotNull(b.A); - Assert.Same(b, b.A.B); - Assert.Same(b.A, b.A.B.A); - } + [Fact] + public void HandlesEagerMefNonPrerequisiteCircularity2() + { + var container = RegisterTypeCatalogContaining(typeof(EagerCircularA), typeof(EagerCircularB)); + var b = container.Resolve(); + Assert.NotNull(b); + Assert.NotNull(b.A); + Assert.Same(b, b.A.B); + Assert.Same(b.A, b.A.B.A); + } - [Export] - private class LazyCircularA + [Export] + private class LazyCircularA + { + [ImportingConstructor] + public LazyCircularA(Lazy b) { - [ImportingConstructor] - public LazyCircularA(Lazy b) - { - B = b; - } - - public Lazy B { get; private set; } + B = b; } - [Export] - private class LazyCircularB - { - [Import] - public Lazy A { get; set; } - } + public Lazy B { get; private set; } + } - /* Non-lazy circular dependencies in MEF have to be done with - * properties. Constructor parameters will throw a MEF composition - * exception. */ + [Export] + private class LazyCircularB + { + [Import] + public Lazy A { get; set; } + } - [Export] - private class EagerCircularA - { - [Import] - public EagerCircularB B { get; private set; } - } + /* Non-lazy circular dependencies in MEF have to be done with + * properties. Constructor parameters will throw a MEF composition + * exception. */ - [Export] - private class EagerCircularB - { - [Import] - public EagerCircularA A { get; set; } - } + [Export] + private class EagerCircularA + { + [Import] + public EagerCircularB B { get; private set; } + } + + [Export] + private class EagerCircularB + { + [Import] + public EagerCircularA A { get; set; } } } diff --git a/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs index b5eb8d5..3a8b533 100644 --- a/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/DisposalRegistrationTests.cs @@ -5,98 +5,97 @@ using System.ComponentModel.Composition.Hosting; using Autofac.Util; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class DisposalRegistrationTests { - public class DisposalRegistrationTests + [Fact] + public void DefaultLifetimeForMefComponentsIsSingleton() { - [Fact] - public void DefaultLifetimeForMefComponentsIsSingleton() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(HasDefaultCreationPolicy)); - builder.RegisterComposablePartCatalog(catalog); - AssertDisposalTrackerIsSingleton(builder); - } + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(HasDefaultCreationPolicy)); + builder.RegisterComposablePartCatalog(catalog); + AssertDisposalTrackerIsSingleton(builder); + } - [Fact] - public void RespectsSharedCreationPolicy() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(HasSharedCreationPolicy)); - builder.RegisterComposablePartCatalog(catalog); - AssertDisposalTrackerIsSingleton(builder); - } + [Fact] + public void RespectsSharedCreationPolicy() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(HasSharedCreationPolicy)); + builder.RegisterComposablePartCatalog(catalog); + AssertDisposalTrackerIsSingleton(builder); + } - [Fact] - public void AnyCreationPolicyDefaultsToShared() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(HasAnyCreationPolicy)); - builder.RegisterComposablePartCatalog(catalog); - AssertDisposalTrackerIsSingleton(builder); - } + [Fact] + public void AnyCreationPolicyDefaultsToShared() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(HasAnyCreationPolicy)); + builder.RegisterComposablePartCatalog(catalog); + AssertDisposalTrackerIsSingleton(builder); + } - private static void AssertDisposalTrackerIsSingleton(ContainerBuilder builder) - { - var container = builder.Build(); - var instance1 = container.Resolve(); - var instance2 = container.Resolve(); - Assert.Same(instance1, instance2); - Assert.False(instance1.IsDisposedPublic); - container.Dispose(); - Assert.True(instance1.IsDisposedPublic); - } + private static void AssertDisposalTrackerIsSingleton(ContainerBuilder builder) + { + var container = builder.Build(); + var instance1 = container.Resolve(); + var instance2 = container.Resolve(); + Assert.Same(instance1, instance2); + Assert.False(instance1.IsDisposedPublic); + container.Dispose(); + Assert.True(instance1.IsDisposedPublic); + } - [Fact] - public void RespectsNonSharedCreationPolicy() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(HasNonSharedCreationPolicy)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var instance1 = container.Resolve(); - var instance2 = container.Resolve(); - Assert.IsAssignableFrom(instance1); - Assert.NotSame(instance1, instance2); - Assert.False(instance1.IsDisposedPublic); - Assert.False(instance2.IsDisposedPublic); - container.Dispose(); - Assert.True(instance1.IsDisposedPublic); - Assert.True(instance2.IsDisposedPublic); - } + [Fact] + public void RespectsNonSharedCreationPolicy() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(HasNonSharedCreationPolicy)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var instance1 = container.Resolve(); + var instance2 = container.Resolve(); + Assert.IsAssignableFrom(instance1); + Assert.NotSame(instance1, instance2); + Assert.False(instance1.IsDisposedPublic); + Assert.False(instance2.IsDisposedPublic); + container.Dispose(); + Assert.True(instance1.IsDisposedPublic); + Assert.True(instance2.IsDisposedPublic); + } - private class DisposalTracker : Disposable + private class DisposalTracker : Disposable + { + public bool IsDisposedPublic { - public bool IsDisposedPublic + get { - get - { - return IsDisposed; - } + return IsDisposed; } } + } - [Export(typeof(DisposalTracker))] - private class HasDefaultCreationPolicy : DisposalTracker - { - } + [Export(typeof(DisposalTracker))] + private class HasDefaultCreationPolicy : DisposalTracker + { + } - [PartCreationPolicy(CreationPolicy.Any)] - [Export(typeof(DisposalTracker))] - private class HasAnyCreationPolicy : DisposalTracker - { - } + [PartCreationPolicy(CreationPolicy.Any)] + [Export(typeof(DisposalTracker))] + private class HasAnyCreationPolicy : DisposalTracker + { + } - [PartCreationPolicy(CreationPolicy.Shared)] - [Export(typeof(DisposalTracker))] - private class HasSharedCreationPolicy : DisposalTracker - { - } + [PartCreationPolicy(CreationPolicy.Shared)] + [Export(typeof(DisposalTracker))] + private class HasSharedCreationPolicy : DisposalTracker + { + } - [PartCreationPolicy(CreationPolicy.NonShared)] - [Export(typeof(DisposalTracker))] - private class HasNonSharedCreationPolicy : DisposalTracker - { - } + [PartCreationPolicy(CreationPolicy.NonShared)] + [Export(typeof(DisposalTracker))] + private class HasNonSharedCreationPolicy : DisposalTracker + { } } diff --git a/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs index 60791f4..275a94b 100644 --- a/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/DynamicTypeExportRegistrationTests.cs @@ -6,189 +6,188 @@ using System.Reflection; using Autofac.Integration.Mef.Test.TestTypes; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class DynamicTypeExportRegistrationTests { - public class DynamicTypeExportRegistrationTests + [Fact] + public void ImportManyFromAutofacExports() { - [Fact] - public void ImportManyFromAutofacExports() + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(ImportManyDependency)); + builder.RegisterComposablePartCatalog(catalog); + foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => + typeof(IAutofacDependency).IsAssignableFrom(type) && !type.IsInterface)) { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(ImportManyDependency)); - builder.RegisterComposablePartCatalog(catalog); - foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => - typeof(IAutofacDependency).IsAssignableFrom(type) && !type.IsInterface)) - { - builder.RegisterType(type).Exported(x => x.As(typeof(IAutofacDependency))); - } - - var container = builder.Build(); - var resolve = container.Resolve(); - Assert.Equal(2, resolve.Dependencies.Count()); + builder.RegisterType(type).Exported(x => x.As(typeof(IAutofacDependency))); } - [Fact] - public void ImportWithMetadataFromAutofacExports() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(ImportWithMetadataDependency)); - builder.RegisterComposablePartCatalog(catalog); - const int metaInt = 10; - foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => - Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) - { - builder.RegisterType(type).Exported(x => x.As(type).WithMetadata("TheInt", metaInt)); - } - - var container = builder.Build(); - var resolve = container.Resolve(); - Assert.NotNull(resolve); - Assert.NotNull(resolve.Dependency.Value); - Assert.Equal(metaInt, resolve.Dependency.Metadata.TheInt); - } + var container = builder.Build(); + var resolve = container.Resolve(); + Assert.Equal(2, resolve.Dependencies.Count()); + } - [Fact] - public void RestrictsExportsBasedOnValueType() + [Fact] + public void ImportWithMetadataFromAutofacExports() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(ImportWithMetadataDependency)); + builder.RegisterComposablePartCatalog(catalog); + const int metaInt = 10; + foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => + Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) { - var builder = new ContainerBuilder(); - const string n = "name"; - foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => - Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) - { - builder.RegisterType(type).Exported(x => x.AsNamed(type, n)); - } - - var container = builder.Build(); - var exports = container.ResolveExports(n); - Assert.Empty(exports); + builder.RegisterType(type).Exported(x => x.As(type).WithMetadata("TheInt", metaInt)); } - [Fact] - public void DuplicateConstructorDependencyImportUsingAttribute() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(ImportsDuplicateAutofacDependency)); - builder.RegisterComposablePartCatalog(catalog); - foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => - Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) - { - builder.RegisterType(type).Exported(x => x.As(type)); - } - - var container = builder.Build(); - var resolved = container.Resolve(); - Assert.NotNull(resolved.First); - Assert.NotNull(resolved.Second); - } + var container = builder.Build(); + var resolve = container.Resolve(); + Assert.NotNull(resolve); + Assert.NotNull(resolve.Dependency.Value); + Assert.Equal(metaInt, resolve.Dependency.Metadata.TheInt); + } - [Fact] - public void DuplicateConstructorDependencyImportUsingInterface() + [Fact] + public void RestrictsExportsBasedOnValueType() + { + var builder = new ContainerBuilder(); + const string n = "name"; + foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => + Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(ImportsDuplicateAutofacDependency)); - builder.RegisterComposablePartCatalog(catalog); - foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => - typeof(IAutofacDependency).IsAssignableFrom(type) && !type.IsInterface)) - { - builder.RegisterType(type).Exported(x => x.As(type)); - } - - var container = builder.Build(); - var resolved = container.Resolve(); - Assert.NotNull(resolved.First); - Assert.NotNull(resolved.Second); + builder.RegisterType(type).Exported(x => x.AsNamed(type, n)); } - [Fact] - public void MixedDependencyConstructorDependencyImport() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(ImportsMixedAutofacMefDependency), typeof(MefDependency)); - builder.RegisterComposablePartCatalog(catalog); - foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => - Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) - { - builder.RegisterType(type).Exported(x => x.As(type)); - } - - var container = builder.Build(); - var resolved = container.Resolve(); - Assert.NotNull(resolved.First); - Assert.NotNull(resolved.Second); - } + var container = builder.Build(); + var exports = container.ResolveExports(n); + Assert.Empty(exports); + } - private interface IAutofacDependency + [Fact] + public void DuplicateConstructorDependencyImportUsingAttribute() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(ImportsDuplicateAutofacDependency)); + builder.RegisterComposablePartCatalog(catalog); + foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => + Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) { + builder.RegisterType(type).Exported(x => x.As(type)); } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - [ExportFromAutofac] - private class ExportFromAutofacDependencyA : IAutofacDependency - { - } + var container = builder.Build(); + var resolved = container.Resolve(); + Assert.NotNull(resolved.First); + Assert.NotNull(resolved.Second); + } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - [ExportFromAutofac] - private class ExportFromAutofacDependencyB : IAutofacDependency + [Fact] + public void DuplicateConstructorDependencyImportUsingInterface() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(ImportsDuplicateAutofacDependency)); + builder.RegisterComposablePartCatalog(catalog); + foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => + typeof(IAutofacDependency).IsAssignableFrom(type) && !type.IsInterface)) { + builder.RegisterType(type).Exported(x => x.As(type)); } - private interface IDependency - { - } + var container = builder.Build(); + var resolved = container.Resolve(); + Assert.NotNull(resolved.First); + Assert.NotNull(resolved.Second); + } - [Export(typeof(IDependency))] - private class MefDependency : IDependency + [Fact] + public void MixedDependencyConstructorDependencyImport() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(ImportsMixedAutofacMefDependency), typeof(MefDependency)); + builder.RegisterComposablePartCatalog(catalog); + foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => + Attribute.GetCustomAttribute(type, typeof(ExportFromAutofacAttribute)) != null)) { + builder.RegisterType(type).Exported(x => x.As(type)); } - [Export] - private class ImportManyDependency - { - [ImportMany] - public IEnumerable Dependencies { get; set; } - } + var container = builder.Build(); + var resolved = container.Resolve(); + Assert.NotNull(resolved.First); + Assert.NotNull(resolved.Second); + } - [Export] - private class ImportWithMetadataDependency - { - [Import] - public Lazy Dependency { get; set; } - } + private interface IAutofacDependency + { + } - [Export] - private class ImportsDuplicateAutofacDependency - { - public ExportFromAutofacDependencyA First { get; } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + [ExportFromAutofac] + private class ExportFromAutofacDependencyA : IAutofacDependency + { + } - public ExportFromAutofacDependencyB Second { get; } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + [ExportFromAutofac] + private class ExportFromAutofacDependencyB : IAutofacDependency + { + } - [ImportingConstructor] - public ImportsDuplicateAutofacDependency(ExportFromAutofacDependencyA first, ExportFromAutofacDependencyB second) - { - First = first; - Second = second; - } - } + private interface IDependency + { + } - [Export] - private class ImportsMixedAutofacMefDependency - { - public ExportFromAutofacDependencyA First { get; } + [Export(typeof(IDependency))] + private class MefDependency : IDependency + { + } - public IDependency Second { get; } + [Export] + private class ImportManyDependency + { + [ImportMany] + public IEnumerable Dependencies { get; set; } + } - [ImportingConstructor] - public ImportsMixedAutofacMefDependency(ExportFromAutofacDependencyA first, IDependency second) - { - First = first; - Second = second; - } + [Export] + private class ImportWithMetadataDependency + { + [Import] + public Lazy Dependency { get; set; } + } + + [Export] + private class ImportsDuplicateAutofacDependency + { + public ExportFromAutofacDependencyA First { get; } + + public ExportFromAutofacDependencyB Second { get; } + + [ImportingConstructor] + public ImportsDuplicateAutofacDependency(ExportFromAutofacDependencyA first, ExportFromAutofacDependencyB second) + { + First = first; + Second = second; } + } - [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] - private sealed class ExportFromAutofacAttribute : Attribute + [Export] + private class ImportsMixedAutofacMefDependency + { + public ExportFromAutofacDependencyA First { get; } + + public IDependency Second { get; } + + [ImportingConstructor] + public ImportsMixedAutofacMefDependency(ExportFromAutofacDependencyA first, IDependency second) { + First = first; + Second = second; } } + + [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] + private sealed class ExportFromAutofacAttribute : Attribute + { + } } diff --git a/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs index 6fed668..587984d 100644 --- a/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/GenericExportRegistrationTests.cs @@ -4,80 +4,79 @@ using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class GenericExportRegistrationTests { - public class GenericExportRegistrationTests + [Fact] + public void RegisterComposablePartCatalog_GenericExport() { - [Fact] - public void RegisterComposablePartCatalog_GenericExport() - { - var container = RegisterTypeCatalogContaining(typeof(IT1), typeof(ITest<>), typeof(Test)); - var b = container.Resolve>(); - Assert.NotNull(b); - Assert.IsType(b); - } + var container = RegisterTypeCatalogContaining(typeof(IT1), typeof(ITest<>), typeof(Test)); + var b = container.Resolve>(); + Assert.NotNull(b); + Assert.IsType(b); + } - [Fact(Skip = "Issue #4")] - public void RegisterComposablePartCatalog_OpenGeneric() - { - // Autofac.Core.Registration.ComponentNotRegisteredException: - // The requested service 'ContractName=Autofac.Integration.Mef.Test.GenericExportRegistrationTests+OpenGenericExport(Autofac.Integration.Mef.Test.GenericExportRegistrationTests+SimpleType)' has not been registered. - var container = RegisterTypeCatalogContaining(typeof(OpenGenericExport<>), typeof(SimpleType), typeof(OpenGenericConsumer)); - var b = container.Resolve(); - Assert.NotNull(b); - } + [Fact(Skip = "Issue #4")] + public void RegisterComposablePartCatalog_OpenGeneric() + { + // Autofac.Core.Registration.ComponentNotRegisteredException: + // The requested service 'ContractName=Autofac.Integration.Mef.Test.GenericExportRegistrationTests+OpenGenericExport(Autofac.Integration.Mef.Test.GenericExportRegistrationTests+SimpleType)' has not been registered. + var container = RegisterTypeCatalogContaining(typeof(OpenGenericExport<>), typeof(SimpleType), typeof(OpenGenericConsumer)); + var b = container.Resolve(); + Assert.NotNull(b); + } - private static IContainer RegisterTypeCatalogContaining(params Type[] types) - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(types); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - return container; - } + private static IContainer RegisterTypeCatalogContaining(params Type[] types) + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(types); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + return container; + } - [InheritedExport] - private interface ITest - { - } + [InheritedExport] + private interface ITest + { + } - private interface IT1 - { - } + private interface IT1 + { + } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - private class Test : ITest - { - } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class Test : ITest + { + } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - private class TestConsumer - { - [Import] - public ITest Property { get; set; } - } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class TestConsumer + { + [Import] + public ITest Property { get; set; } + } - [Export(typeof(OpenGenericExport<>))] - private class OpenGenericExport + [Export(typeof(OpenGenericExport<>))] + private class OpenGenericExport + { + [ImportingConstructor] + public OpenGenericExport(T t) { - [ImportingConstructor] - public OpenGenericExport(T t) - { - } } + } - [Export] - private class SimpleType - { - } + [Export] + private class SimpleType + { + } - [Export] - private class OpenGenericConsumer + [Export] + private class OpenGenericConsumer + { + [ImportingConstructor] + public OpenGenericConsumer(OpenGenericExport o) { - [ImportingConstructor] - public OpenGenericConsumer(OpenGenericExport o) - { - } } } } diff --git a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs index ea7f9df..1a572d3 100644 --- a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs @@ -6,150 +6,149 @@ using System.Reflection; using Autofac.Integration.Mef.Test.TestTypes; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class LazyWithMetadataWhenMetadataIsSuppliedTests { - public class LazyWithMetadataWhenMetadataIsSuppliedTests - { - private const int SuppliedValue = 123; + private const int SuppliedValue = 123; - private readonly IContainer _container; + private readonly IContainer _container; - public LazyWithMetadataWhenMetadataIsSuppliedTests() - { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - builder.RegisterType().WithMetadata("TheInt", SuppliedValue); + public LazyWithMetadataWhenMetadataIsSuppliedTests() + { + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + builder.RegisterType().WithMetadata("TheInt", SuppliedValue); - using var catalog = new TypeCatalog(typeof(ThrowingService), typeof(ServiceConsumer), typeof(NotThrowingService), typeof(SingleServiceConsumer), typeof(ServiceConsumerFromParameters)); - builder.RegisterComposablePartCatalog(catalog); - _container = builder.Build(); - } + using var catalog = new TypeCatalog(typeof(ThrowingService), typeof(ServiceConsumer), typeof(NotThrowingService), typeof(SingleServiceConsumer), typeof(ServiceConsumerFromParameters)); + builder.RegisterComposablePartCatalog(catalog); + _container = builder.Build(); + } - [SuppressMessage("CA1034", "CA1034", Justification = "Metadata classes must be public for MEF.")] - public interface INameMetadata - { - string Name { get; } - } + [SuppressMessage("CA1034", "CA1034", Justification = "Metadata classes must be public for MEF.")] + public interface INameMetadata + { + string Name { get; } + } - internal interface IService - { - } + internal interface IService + { + } - [Fact] - public void InstanceShouldNotBeCreated() - { - // Issue #1: Lazy dependencies shouldn't be instantiated in the Lazy relationship. - var serviceConsumer = _container.Resolve(); - Assert.Equal(2, serviceConsumer.Services.Count()); - var service = serviceConsumer.Services?.FirstOrDefault(x => x.Metadata.Name == "will-throw-on-ctor"); - Assert.NotNull(service); - Assert.False(service.IsValueCreated); - var ex = Assert.Throws(() => { _ = service.Value; }); - Assert.Contains("This service should never be created", ex.ToString(), StringComparison.OrdinalIgnoreCase); - } + [Fact] + public void InstanceShouldNotBeCreated() + { + // Issue #1: Lazy dependencies shouldn't be instantiated in the Lazy relationship. + var serviceConsumer = _container.Resolve(); + Assert.Equal(2, serviceConsumer.Services.Count()); + var service = serviceConsumer.Services?.FirstOrDefault(x => x.Metadata.Name == "will-throw-on-ctor"); + Assert.NotNull(service); + Assert.False(service.IsValueCreated); + var ex = Assert.Throws(() => { _ = service.Value; }); + Assert.Contains("This service should never be created", ex.ToString(), StringComparison.OrdinalIgnoreCase); + } - [Fact] - public void InstanceShouldNotBeCreatedAsParameters() - { - // Issue #1: Lazy dependencies shouldn't be instantiated in the Lazy relationship. - var serviceConsumer = _container.Resolve(); - Assert.Equal(2, serviceConsumer.Services.Count()); - var service = serviceConsumer.Services?.FirstOrDefault(x => x.Metadata.Name == "will-throw-on-ctor"); - Assert.NotNull(service); - Assert.False(service.IsValueCreated); - var ex = Assert.Throws(() => { _ = service.Value; }); - Assert.Contains("This service should never be created", ex.ToString(), StringComparison.OrdinalIgnoreCase); - } + [Fact] + public void InstanceShouldNotBeCreatedAsParameters() + { + // Issue #1: Lazy dependencies shouldn't be instantiated in the Lazy relationship. + var serviceConsumer = _container.Resolve(); + Assert.Equal(2, serviceConsumer.Services.Count()); + var service = serviceConsumer.Services?.FirstOrDefault(x => x.Metadata.Name == "will-throw-on-ctor"); + Assert.NotNull(service); + Assert.False(service.IsValueCreated); + var ex = Assert.Throws(() => { _ = service.Value; }); + Assert.Contains("This service should never be created", ex.ToString(), StringComparison.OrdinalIgnoreCase); + } - [Fact] - public void InstanceShouldNotBeCreatedWithSingle() - { - var serviceConsumer = _container.Resolve(); - Assert.False(serviceConsumer.Service.IsValueCreated); - } + [Fact] + public void InstanceShouldNotBeCreatedWithSingle() + { + var serviceConsumer = _container.Resolve(); + Assert.False(serviceConsumer.Service.IsValueCreated); + } - [Fact] - public void InstanceShouldNotBeCreatedWhenPullingDirectly() - { - var service = _container.Resolve>(); - Assert.NotNull(service); - Assert.False(service.IsValueCreated); - } + [Fact] + public void InstanceShouldNotBeCreatedWhenPullingDirectly() + { + var service = _container.Resolve>(); + Assert.NotNull(service); + Assert.False(service.IsValueCreated); + } - [Fact] - public void InstanceShouldNotBeCreatedWhenUsingCollection() - { - var l = _container.Resolve>>(); - var service = l.First(); - Assert.NotNull(service); - Assert.False(service.IsValueCreated); - } + [Fact] + public void InstanceShouldNotBeCreatedWhenUsingCollection() + { + var l = _container.Resolve>>(); + var service = l.First(); + Assert.NotNull(service); + Assert.False(service.IsValueCreated); + } - [Fact] - public void ValuesAreProvidedFromMetadata() - { - var meta = _container.Resolve>(); - Assert.Equal(SuppliedValue, meta.Metadata.TheInt); - } + [Fact] + public void ValuesAreProvidedFromMetadata() + { + var meta = _container.Resolve>(); + Assert.Equal(SuppliedValue, meta.Metadata.TheInt); + } - [Fact] - public void ValuesBubbleUpThroughAdapters() - { - var meta = _container.Resolve, IMeta>>(); - Assert.Equal(SuppliedValue, meta.Metadata.TheInt); - } + [Fact] + public void ValuesBubbleUpThroughAdapters() + { + var meta = _container.Resolve, IMeta>>(); + Assert.Equal(SuppliedValue, meta.Metadata.TheInt); + } - [Fact] - public void ValuesProvidedFromMetadataOverrideDefaults() - { - var meta = _container.Resolve>(); - Assert.Equal(SuppliedValue, meta.Metadata.TheInt); - } + [Fact] + public void ValuesProvidedFromMetadataOverrideDefaults() + { + var meta = _container.Resolve>(); + Assert.Equal(SuppliedValue, meta.Metadata.TheInt); + } - [Export] - internal class ServiceConsumer - { - [ImportMany] - public IEnumerable> Services { get; set; } - } + [Export] + internal class ServiceConsumer + { + [ImportMany] + public IEnumerable> Services { get; set; } + } - [Export] - internal class ServiceConsumerFromParameters + [Export] + internal class ServiceConsumerFromParameters + { + [ImportingConstructor] + public ServiceConsumerFromParameters([ImportMany]IEnumerable> services) { - [ImportingConstructor] - public ServiceConsumerFromParameters([ImportMany]IEnumerable> services) - { - Services = services; - } - - public IEnumerable> Services { get; } + Services = services; } - [Export] - internal class SingleServiceConsumer - { - [Import] - public Lazy Service { get; set; } - } + public IEnumerable> Services { get; } + } + + [Export] + internal class SingleServiceConsumer + { + [Import] + public Lazy Service { get; set; } + } - [Export(typeof(IService))] - [Export(typeof(ThrowingService))] - [ExportMetadata("Name", "will-throw-on-ctor")] - internal class ThrowingService : IService + [Export(typeof(IService))] + [Export(typeof(ThrowingService))] + [ExportMetadata("Name", "will-throw-on-ctor")] + internal class ThrowingService : IService + { + public ThrowingService() { - public ThrowingService() - { - throw new InvalidOperationException("This service should never be created"); - } + throw new InvalidOperationException("This service should never be created"); } + } - [Export(typeof(IService))] - [ExportMetadata("Name", "will-not-throw-on-ctor")] - internal class NotThrowingService : IService + [Export(typeof(IService))] + [ExportMetadata("Name", "will-not-throw-on-ctor")] + internal class NotThrowingService : IService + { + public NotThrowingService() { - public NotThrowingService() - { - } } } } diff --git a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests.cs index 6a03680..ec38e47 100644 --- a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests.cs @@ -5,33 +5,32 @@ using Autofac.Core; using Autofac.Integration.Mef.Test.TestTypes; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests { - public class LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests - { - private readonly IContainer _container; + private readonly IContainer _container; - public LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests() - { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - builder.RegisterType(); - _container = builder.Build(); - } + public LazyWithMetadataWhenNoMatchingMetadataIsSuppliedTests() + { + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + builder.RegisterType(); + _container = builder.Build(); + } - [Fact] - public void ResolvingStronglyTypedMetadataWithoutDefaultValueThrowsException() - { - var dx = Assert.Throws(() => _container.Resolve>()); + [Fact] + public void ResolvingStronglyTypedMetadataWithoutDefaultValueThrowsException() + { + var dx = Assert.Throws(() => _container.Resolve>()); - Assert.IsType(dx.InnerException); - } + Assert.IsType(dx.InnerException); + } - [Fact] - public void ResolvingStronglyTypedMetadataWithDefaultValueProvidesDefault() - { - var m = _container.Resolve>(); - Assert.Equal(42, m.Metadata.TheInt); - } + [Fact] + public void ResolvingStronglyTypedMetadataWithDefaultValueProvidesDefault() + { + var m = _container.Resolve>(); + Assert.Equal(42, m.Metadata.TheInt); } } diff --git a/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs b/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs index cd0655c..58bcf14 100644 --- a/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs +++ b/test/Autofac.Integration.Mef.Test/LifetimeScenariosTests.cs @@ -7,119 +7,118 @@ using Autofac.Features.Metadata; using Autofac.Integration.Mef.Test.TestTypes; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class LifetimeScenariosTests { - public class LifetimeScenariosTests + [Fact] + public void ClassRegisteredInAutofacAsFactoryScopedIsResolvedByMefAsFactoryScoped() { - [Fact] - public void ClassRegisteredInAutofacAsFactoryScopedIsResolvedByMefAsFactoryScoped() - { - var containerBuilder = new ContainerBuilder(); + var containerBuilder = new ContainerBuilder(); - using var newAssemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); - containerBuilder.RegisterComposablePartCatalog(newAssemblyCatalog); - containerBuilder.RegisterType(); - containerBuilder.RegisterType() - .Exported(e => e.As()); + using var newAssemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); + containerBuilder.RegisterComposablePartCatalog(newAssemblyCatalog); + containerBuilder.RegisterType(); + containerBuilder.RegisterType() + .Exported(e => e.As()); - var autofacContainer = containerBuilder.Build(); + var autofacContainer = containerBuilder.Build(); - var elementFromAutofac1 = autofacContainer.Resolve(); - var elementFromAutofac2 = autofacContainer.Resolve(); + var elementFromAutofac1 = autofacContainer.Resolve(); + var elementFromAutofac2 = autofacContainer.Resolve(); - Assert.NotSame(elementFromAutofac1, elementFromAutofac2); - Assert.NotSame(elementFromAutofac1.ImportedFormMef, elementFromAutofac2.ImportedFormMef); - Assert.NotSame(elementFromAutofac1.ImportedFormMef.ImportedFormAutofac, elementFromAutofac2.ImportedFormMef.ImportedFormAutofac); - } + Assert.NotSame(elementFromAutofac1, elementFromAutofac2); + Assert.NotSame(elementFromAutofac1.ImportedFormMef, elementFromAutofac2.ImportedFormMef); + Assert.NotSame(elementFromAutofac1.ImportedFormMef.ImportedFormAutofac, elementFromAutofac2.ImportedFormMef.ImportedFormAutofac); + } - [Fact] - public void LazyMetadataRegistrationSourceDoesNotDuplicateDependencies() + [Fact] + public void LazyMetadataRegistrationSourceDoesNotDuplicateDependencies() + { + // Issue #23 - configuration action on BeginLifetimeScope causes duplicate resolutions. + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + builder.RegisterAssemblyTypes(typeof(LifetimeScenariosTests).Assembly) + .AssignableTo() + .As() + .WithMetadataFrom(); + var container = builder.Build(); + + using (var scope = container.BeginLifetimeScope()) { - // Issue #23 - configuration action on BeginLifetimeScope causes duplicate resolutions. - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - builder.RegisterAssemblyTypes(typeof(LifetimeScenariosTests).Assembly) - .AssignableTo() - .As() - .WithMetadataFrom(); - var container = builder.Build(); - - using (var scope = container.BeginLifetimeScope()) - { - var deps = scope.Resolve>>(); - Assert.Equal(2, deps.Count()); - } - - using (var scope = container.BeginLifetimeScope(b => { })) - { - var deps = scope.Resolve>>(); - Assert.Equal(2, deps.Count()); - } + var deps = scope.Resolve>>(); + Assert.Equal(2, deps.Count()); } - [Fact] - public void StronglyTypedMetadataRegistrationSourceDoesNotDuplicateDependencies() + using (var scope = container.BeginLifetimeScope(b => { })) { - // Issue #23 - configuration action on BeginLifetimeScope causes duplicate resolutions. - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - builder.RegisterAssemblyTypes(typeof(LifetimeScenariosTests).Assembly) - .AssignableTo() - .As() - .WithMetadataFrom(); - var container = builder.Build(); - - using (var scope = container.BeginLifetimeScope()) - { - var deps = scope.Resolve>>(); - Assert.Equal(2, deps.Count()); - } - - using (var scope = container.BeginLifetimeScope(b => { })) - { - var deps = scope.Resolve>>(); - Assert.Equal(2, deps.Count()); - } + var deps = scope.Resolve>>(); + Assert.Equal(2, deps.Count()); } + } - private interface IDependency + [Fact] + public void StronglyTypedMetadataRegistrationSourceDoesNotDuplicateDependencies() + { + // Issue #23 - configuration action on BeginLifetimeScope causes duplicate resolutions. + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + builder.RegisterAssemblyTypes(typeof(LifetimeScenariosTests).Assembly) + .AssignableTo() + .As() + .WithMetadataFrom(); + var container = builder.Build(); + + using (var scope = container.BeginLifetimeScope()) { + var deps = scope.Resolve>>(); + Assert.Equal(2, deps.Count()); } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - [Meta(1)] - private class Dependency1 : IDependency + using (var scope = container.BeginLifetimeScope(b => { })) { + var deps = scope.Resolve>>(); + Assert.Equal(2, deps.Count()); } + } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - [Meta(2)] - private class Dependency2 : IDependency - { - } + private interface IDependency + { + } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - private class RegisteredInAutofac - { - public ExportedToMefAndImportingFromAutofac ImportedFormMef { get; set; } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + [Meta(1)] + private class Dependency1 : IDependency + { + } - public RegisteredInAutofac(ExportedToMefAndImportingFromAutofac importedFormMef) - { - ImportedFormMef = importedFormMef; - } - } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + [Meta(2)] + private class Dependency2 : IDependency + { + } - [Export] - [PartCreationPolicy(CreationPolicy.NonShared)] - private class ExportedToMefAndImportingFromAutofac - { - [Import] - public RegisteredInAutofacAndExported ImportedFormAutofac { get; set; } - } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class RegisteredInAutofac + { + public ExportedToMefAndImportingFromAutofac ImportedFormMef { get; set; } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - private class RegisteredInAutofacAndExported + public RegisteredInAutofac(ExportedToMefAndImportingFromAutofac importedFormMef) { + ImportedFormMef = importedFormMef; } } + + [Export] + [PartCreationPolicy(CreationPolicy.NonShared)] + private class ExportedToMefAndImportingFromAutofac + { + [Import] + public RegisteredInAutofacAndExported ImportedFormAutofac { get; set; } + } + + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class RegisteredInAutofacAndExported + { + } } diff --git a/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs index ab92a0c..63cf296 100644 --- a/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/MetadataRegistrationTests.cs @@ -7,172 +7,171 @@ using Autofac.Features.Metadata; using Autofac.Integration.Mef.Test.TestTypes; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class MetadataRegistrationTests { - public class MetadataRegistrationTests + [Fact] + public void RegisterMetadataRegistrationSources_WhenContainerBuilt_AddsStronglyTypedMetaRegistrationSource() { - [Fact] - public void RegisterMetadataRegistrationSources_WhenContainerBuilt_AddsStronglyTypedMetaRegistrationSource() - { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - var container = builder.Build(); + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + var container = builder.Build(); - var stronglyTypedMetaCount = container.ComponentRegistry.Sources - .Count(source => source is StronglyTypedMetadataRegistrationSource); + var stronglyTypedMetaCount = container.ComponentRegistry.Sources + .Count(source => source is StronglyTypedMetadataRegistrationSource); - Assert.Equal(1, stronglyTypedMetaCount); - } + Assert.Equal(1, stronglyTypedMetaCount); + } - [Fact] - public void RegisterMetadataRegistrationSources_WhenContainerBuilt_AddsLazyWithMetadataRegistrationSource() - { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - var container = builder.Build(); + [Fact] + public void RegisterMetadataRegistrationSources_WhenContainerBuilt_AddsLazyWithMetadataRegistrationSource() + { + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + var container = builder.Build(); - var lazyWithMetadataCount = container.ComponentRegistry.Sources.Count( - source => source is LazyWithMetadataRegistrationSource); + var lazyWithMetadataCount = container.ComponentRegistry.Sources.Count( + source => source is LazyWithMetadataRegistrationSource); - Assert.Equal(1, lazyWithMetadataCount); - } + Assert.Equal(1, lazyWithMetadataCount); + } - [Fact] - public void WithMetadata_InterfaceBasedMetadata_SupportLazyWithMetadata() - { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - builder.Register(c => new object()).WithMetadata(m => - m.For(value => value.TheInt, 42)); - var container = builder.Build(); + [Fact] + public void WithMetadata_InterfaceBasedMetadata_SupportLazyWithMetadata() + { + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + builder.Register(c => new object()).WithMetadata(m => + m.For(value => value.TheInt, 42)); + var container = builder.Build(); - var lazy = container.Resolve>(); + var lazy = container.Resolve>(); - Assert.Equal(42, lazy.Metadata.TheInt); - Assert.NotNull(lazy.Value); - } + Assert.Equal(42, lazy.Metadata.TheInt); + Assert.NotNull(lazy.Value); + } - [Fact] - public void WithMetadata_InterfaceBasedMetadata_SupportMeta() - { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - builder.Register(c => new object()).WithMetadata(m => - m.For(value => value.TheInt, 42)); - var container = builder.Build(); + [Fact] + public void WithMetadata_InterfaceBasedMetadata_SupportMeta() + { + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + builder.Register(c => new object()).WithMetadata(m => + m.For(value => value.TheInt, 42)); + var container = builder.Build(); - var meta = container.Resolve>(); + var meta = container.Resolve>(); - Assert.Equal(42, meta.Metadata.TheInt); - Assert.NotNull(meta.Value); - } + Assert.Equal(42, meta.Metadata.TheInt); + Assert.NotNull(meta.Value); + } - [Fact] - public void ExcludesExportsWithoutRequiredMetadata() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(RequiresMetadataAllowsDefault), typeof(HasNoMetadata)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var rm = container.Resolve(); - Assert.Null(rm.Dependency); - } + [Fact] + public void ExcludesExportsWithoutRequiredMetadata() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(RequiresMetadataAllowsDefault), typeof(HasNoMetadata)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var rm = container.Resolve(); + Assert.Null(rm.Dependency); + } - [Fact] - public void IncludesExportsWithRequiredMetadata() - { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - using var catalog = new TypeCatalog(typeof(RequiresMetadata), typeof(HasMetadata)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var rm = container.Resolve(); - Assert.NotNull(rm.Dependency); - } + [Fact] + public void IncludesExportsWithRequiredMetadata() + { + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + using var catalog = new TypeCatalog(typeof(RequiresMetadata), typeof(HasMetadata)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var rm = container.Resolve(); + Assert.NotNull(rm.Dependency); + } - [Fact] - public void SupportsMetadataOnAutofacExports() + [Fact] + public void SupportsMetadataOnAutofacExports() + { + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + var metadata = new Dictionary { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - var metadata = new Dictionary - { - { "Key", "Value" }, - }; - const string exportedString = "Hello"; - builder.RegisterInstance(exportedString).Exported(e => e.As().WithMetadata(metadata)); - using var catalog = new TypeCatalog(typeof(RequiresMetadata)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var rm = container.Resolve(); - Assert.NotNull(rm.Dependency); - Assert.Equal("Hello", rm.Dependency.Value); - } + { "Key", "Value" }, + }; + const string exportedString = "Hello"; + builder.RegisterInstance(exportedString).Exported(e => e.As().WithMetadata(metadata)); + using var catalog = new TypeCatalog(typeof(RequiresMetadata)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var rm = container.Resolve(); + Assert.NotNull(rm.Dependency); + Assert.Equal("Hello", rm.Dependency.Value); + } - [Fact] - public void SetsMultipleExportsToZeroOrMoreCardinalityImports() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog( - typeof(ImportsMany), typeof(HasMetadata), typeof(HasNoMetadata)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var rm = container.Resolve(); - Assert.NotNull(rm.Dependencies); - Assert.Equal(2, rm.Dependencies.Count); - } + [Fact] + public void SetsMultipleExportsToZeroOrMoreCardinalityImports() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog( + typeof(ImportsMany), typeof(HasMetadata), typeof(HasNoMetadata)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var rm = container.Resolve(); + Assert.NotNull(rm.Dependencies); + Assert.Equal(2, rm.Dependencies.Count); + } - [SuppressMessage("CA1034", "CA1034", Justification = "Metadata classes must be public for MEF.")] - public interface IRequiredMetadata - { - string Key { get; } - } + [SuppressMessage("CA1034", "CA1034", Justification = "Metadata classes must be public for MEF.")] + public interface IRequiredMetadata + { + string Key { get; } + } - [Export] - private class RequiresMetadata - { - [Import] - public Lazy Dependency { get; set; } - } + [Export] + private class RequiresMetadata + { + [Import] + public Lazy Dependency { get; set; } + } - [Export] - private class RequiresMetadataAllowsDefault - { - [Import(AllowDefault = true)] - public Lazy Dependency { get; set; } - } + [Export] + private class RequiresMetadataAllowsDefault + { + [Import(AllowDefault = true)] + public Lazy Dependency { get; set; } + } - [Export] - private class ImportsMany - { - [ImportMany] - public Collection Dependencies { get; private set; } - } + [Export] + private class ImportsMany + { + [ImportMany] + public Collection Dependencies { get; private set; } + } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - private class HasNoMetadata + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class HasNoMetadata + { + [Export] + public string Service { - [Export] - public string Service + get { - get - { - return "Bar"; - } + return "Bar"; } } + } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - private class HasMetadata + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class HasMetadata + { + [Export] + [ExportMetadata("Key", "Foo")] + public string Service { - [Export] - [ExportMetadata("Key", "Foo")] - public string Service + get { - get - { - return "Bar"; - } + return "Bar"; } } } diff --git a/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs index aed17d2..9863e4c 100644 --- a/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/MultipleExportRegistrationTests.cs @@ -5,63 +5,62 @@ using System.ComponentModel.Composition.Hosting; using Autofac.Core; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class MultipleExportRegistrationTests { - public class MultipleExportRegistrationTests + [Fact] + public void ImportsEmptyCollectionIfDependencyMissing() { - [Fact] - public void ImportsEmptyCollectionIfDependencyMissing() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(ImportsMany)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var im = container.Resolve(); - Assert.NotNull(im.Dependencies); - Assert.False(im.Dependencies.Any()); - } + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(ImportsMany)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var im = container.Resolve(); + Assert.NotNull(im.Dependencies); + Assert.False(im.Dependencies.Any()); + } - [Fact] - public void RespectsExplicitInterchangeServices() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(HasMultipleExports)); + [Fact] + public void RespectsExplicitInterchangeServices() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(HasMultipleExports)); - var interchangeService1 = new TypedService(typeof(HasMultipleExportsBase)); - var interchangeService2 = new KeyedService("b", typeof(HasMultipleExports)); - var nonInterchangeService1 = new TypedService(typeof(HasMultipleExports)); - var nonInterchangeService2 = new KeyedService("a", typeof(HasMultipleExports)); + var interchangeService1 = new TypedService(typeof(HasMultipleExportsBase)); + var interchangeService2 = new KeyedService("b", typeof(HasMultipleExports)); + var nonInterchangeService1 = new TypedService(typeof(HasMultipleExports)); + var nonInterchangeService2 = new KeyedService("a", typeof(HasMultipleExports)); - builder.RegisterComposablePartCatalog( - catalog, - interchangeService1, - interchangeService2); + builder.RegisterComposablePartCatalog( + catalog, + interchangeService1, + interchangeService2); - var container = builder.Build(); + var container = builder.Build(); - Assert.True(container.IsRegisteredService(interchangeService1)); - Assert.True(container.IsRegisteredService(interchangeService2)); - Assert.False(container.IsRegisteredService(nonInterchangeService1)); - Assert.False(container.IsRegisteredService(nonInterchangeService2)); - } + Assert.True(container.IsRegisteredService(interchangeService1)); + Assert.True(container.IsRegisteredService(interchangeService2)); + Assert.False(container.IsRegisteredService(nonInterchangeService1)); + Assert.False(container.IsRegisteredService(nonInterchangeService2)); + } - private class HasMultipleExportsBase - { - } + private class HasMultipleExportsBase + { + } - [Export("a")] - [Export("b")] - [Export(typeof(HasMultipleExportsBase))] - [Export(typeof(HasMultipleExports))] - private class HasMultipleExports : HasMultipleExportsBase - { - } + [Export("a")] + [Export("b")] + [Export(typeof(HasMultipleExportsBase))] + [Export(typeof(HasMultipleExports))] + private class HasMultipleExports : HasMultipleExportsBase + { + } - [Export] - private class ImportsMany - { - [ImportMany] - public List Dependencies { get; set; } - } + [Export] + private class ImportsMany + { + [ImportMany] + public List Dependencies { get; set; } } } diff --git a/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs b/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs index 0e99c02..4062e00 100644 --- a/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs +++ b/test/Autofac.Integration.Mef.Test/SimpleRegistrationTests.cs @@ -5,158 +5,157 @@ using System.ComponentModel.Composition.Hosting; using Autofac.Core.Registration; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class SimpleRegistrationTests { - public class SimpleRegistrationTests + [Fact] + public void MissingDependencyDetected() { - [Fact] - public void MissingDependencyDetected() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(HasMissingDependency)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - Assert.Throws(() => container.Resolve()); - } + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(HasMissingDependency)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + Assert.Throws(() => container.Resolve()); + } - [Fact] - public void RetrievesExportedInterfaceFromCatalogPart() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(MefDependency)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var foo = container.Resolve(); - Assert.IsAssignableFrom(foo); - } + [Fact] + public void RetrievesExportedInterfaceFromCatalogPart() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(MefDependency)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var foo = container.Resolve(); + Assert.IsAssignableFrom(foo); + } - [Fact] - public void SatisfiesImportOnMefComponentFromAutofac() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(ImportsMefDependency)); - builder.RegisterComposablePartCatalog(catalog); - builder.RegisterType().Exported(e => e.As()); - var container = builder.Build(); - var bar = container.Resolve(); - Assert.NotNull(bar.Dependency); - } + [Fact] + public void SatisfiesImportOnMefComponentFromAutofac() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(ImportsMefDependency)); + builder.RegisterComposablePartCatalog(catalog); + builder.RegisterType().Exported(e => e.As()); + var container = builder.Build(); + var bar = container.Resolve(); + Assert.NotNull(bar.Dependency); + } - [Fact] - public void SatisfiesImportOnMefComponentFromMef() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(MefDependency), typeof(ImportsMefDependency)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var bar = container.Resolve(); - Assert.NotNull(bar.Dependency); - } + [Fact] + public void SatisfiesImportOnMefComponentFromMef() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(MefDependency), typeof(ImportsMefDependency)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var bar = container.Resolve(); + Assert.NotNull(bar.Dependency); + } - [Fact] - public void ResolvesExportsFromContext() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(MefDependency)); - builder.RegisterComposablePartCatalog(catalog); - builder.RegisterType().Exported(e => e.As()); - var container = builder.Build(); - var exports = container.ResolveExports(); - Assert.Equal(2, exports.Count()); - } + [Fact] + public void ResolvesExportsFromContext() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(MefDependency)); + builder.RegisterComposablePartCatalog(catalog); + builder.RegisterType().Exported(e => e.As()); + var container = builder.Build(); + var exports = container.ResolveExports(); + Assert.Equal(2, exports.Count()); + } - [Fact] - public void RestrictsExportsBasedOnValueType() - { - var builder = new ContainerBuilder(); - const string n = "name"; - builder.RegisterType().Exported(e => e.AsNamed(n)); - builder.RegisterType().Exported(e => e.AsNamed(n)); - var container = builder.Build(); - var exports = container.ResolveExports(n); - Assert.Single(exports); - } + [Fact] + public void RestrictsExportsBasedOnValueType() + { + var builder = new ContainerBuilder(); + const string n = "name"; + builder.RegisterType().Exported(e => e.AsNamed(n)); + builder.RegisterType().Exported(e => e.AsNamed(n)); + var container = builder.Build(); + var exports = container.ResolveExports(n); + Assert.Single(exports); + } - [Fact] - public void ObjectExportsSupportedByName() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(ObjectExportDerivedClass), typeof(ObjectExportImporter)); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var importer = container.Resolve(); - Assert.NotNull(importer.Item); - } + [Fact] + public void ObjectExportsSupportedByName() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(ObjectExportDerivedClass), typeof(ObjectExportImporter)); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var importer = container.Resolve(); + Assert.NotNull(importer.Item); + } - [Fact] - public void DuplicateConstructorDependency() - { - var builder = new ContainerBuilder(); - using var catalog = new TypeCatalog(typeof(MefDependency), typeof(ImportsMefDependency)); - builder.RegisterType(); - builder.RegisterComposablePartCatalog(catalog); - var container = builder.Build(); - var resolved = container.Resolve(); - Assert.NotNull(resolved.First); - Assert.NotNull(resolved.Second); - } + [Fact] + public void DuplicateConstructorDependency() + { + var builder = new ContainerBuilder(); + using var catalog = new TypeCatalog(typeof(MefDependency), typeof(ImportsMefDependency)); + builder.RegisterType(); + builder.RegisterComposablePartCatalog(catalog); + var container = builder.Build(); + var resolved = container.Resolve(); + Assert.NotNull(resolved.First); + Assert.NotNull(resolved.Second); + } - private interface IDependency - { - } + private interface IDependency + { + } - [Export(typeof(IDependency))] - private class MefDependency : IDependency - { - } + [Export(typeof(IDependency))] + private class MefDependency : IDependency + { + } - [Export] - private class ImportsMefDependency + [Export] + private class ImportsMefDependency + { + [ImportingConstructor] + public ImportsMefDependency(IDependency dependency) { - [ImportingConstructor] - public ImportsMefDependency(IDependency dependency) - { - Dependency = dependency; - } - - public IDependency Dependency { get; private set; } + Dependency = dependency; } - [Export] - private class HasMissingDependency - { - [Import] - public string Dependency { get; set; } - } + public IDependency Dependency { get; private set; } + } - private class ObjectExportBaseClass - { - } + [Export] + private class HasMissingDependency + { + [Import] + public string Dependency { get; set; } + } - [Export("contract-name", typeof(object))] - private class ObjectExportDerivedClass : ObjectExportBaseClass - { - } + private class ObjectExportBaseClass + { + } - [Export] - private class ObjectExportImporter - { - [Import("contract-name")] - public object Item { get; set; } - } + [Export("contract-name", typeof(object))] + private class ObjectExportDerivedClass : ObjectExportBaseClass + { + } - [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] - private class ImportsDuplicateMefClass - { - public ImportsMefDependency First { get; set; } + [Export] + private class ObjectExportImporter + { + [Import("contract-name")] + public object Item { get; set; } + } - public ImportsMefDependency Second { get; set; } + [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated by dependency injection.")] + private class ImportsDuplicateMefClass + { + public ImportsMefDependency First { get; set; } + + public ImportsMefDependency Second { get; set; } - public ImportsDuplicateMefClass(ImportsMefDependency first, ImportsMefDependency second) - { - First = first; - Second = second; - } + public ImportsDuplicateMefClass(ImportsMefDependency first, ImportsMefDependency second) + { + First = first; + Second = second; } } } diff --git a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs index 2eed39b..075b22c 100644 --- a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs @@ -4,41 +4,40 @@ using Autofac.Features.Metadata; using Autofac.Integration.Mef.Test.TestTypes; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class StronglyTypedMetadataWhenMetadataIsSuppliedTests { - public class StronglyTypedMetadataWhenMetadataIsSuppliedTests + private const int SuppliedValue = 123; + + private readonly IContainer _container; + + public StronglyTypedMetadataWhenMetadataIsSuppliedTests() + { + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + builder.RegisterType().WithMetadata("TheInt", SuppliedValue); + _container = builder.Build(); + } + + [Fact] + public void ValuesAreProvidedFromMetadata() + { + var meta = _container.Resolve>(); + Assert.Equal((int)SuppliedValue, (int)meta.Metadata.TheInt); + } + + [Fact] + public void ValuesProvidedFromMetadataOverrideDefaults() + { + var meta = _container.Resolve>(); + Assert.Equal((int)SuppliedValue, (int)meta.Metadata.TheInt); + } + + [Fact] + public void ValuesBubbleUpThroughAdapters() { - private const int SuppliedValue = 123; - - private readonly IContainer _container; - - public StronglyTypedMetadataWhenMetadataIsSuppliedTests() - { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - builder.RegisterType().WithMetadata("TheInt", SuppliedValue); - _container = builder.Build(); - } - - [Fact] - public void ValuesAreProvidedFromMetadata() - { - var meta = _container.Resolve>(); - Assert.Equal((int)SuppliedValue, (int)meta.Metadata.TheInt); - } - - [Fact] - public void ValuesProvidedFromMetadataOverrideDefaults() - { - var meta = _container.Resolve>(); - Assert.Equal((int)SuppliedValue, (int)meta.Metadata.TheInt); - } - - [Fact] - public void ValuesBubbleUpThroughAdapters() - { - var meta = _container.Resolve, IMeta>>(); - Assert.Equal((int)SuppliedValue, (int)meta.Metadata.TheInt); - } + var meta = _container.Resolve, IMeta>>(); + Assert.Equal((int)SuppliedValue, (int)meta.Metadata.TheInt); } } diff --git a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs index 29defaa..289521a 100644 --- a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs @@ -6,32 +6,31 @@ using Autofac.Features.Metadata; using Autofac.Integration.Mef.Test.TestTypes; -namespace Autofac.Integration.Mef.Test +namespace Autofac.Integration.Mef.Test; + +public class StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests { - public class StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests - { - private readonly IContainer _container; + private readonly IContainer _container; - public StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests() - { - var builder = new ContainerBuilder(); - builder.RegisterMetadataRegistrationSources(); - builder.RegisterType(); - _container = builder.Build(); - } + public StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests() + { + var builder = new ContainerBuilder(); + builder.RegisterMetadataRegistrationSources(); + builder.RegisterType(); + _container = builder.Build(); + } - [Fact] - public void ResolvingStronglyTypedMetadataWithoutDefaultValueThrowsException() - { - var dx = Assert.Throws(() => _container.Resolve>()); - Assert.IsType(dx.InnerException); - } + [Fact] + public void ResolvingStronglyTypedMetadataWithoutDefaultValueThrowsException() + { + var dx = Assert.Throws(() => _container.Resolve>()); + Assert.IsType(dx.InnerException); + } - [Fact] - public void ResolvingStronglyTypedMetadataWithDefaultValueProvidesDefault() - { - var m = _container.Resolve>(); - Assert.Equal((int)42, (int)m.Metadata.TheInt); - } + [Fact] + public void ResolvingStronglyTypedMetadataWithDefaultValueProvidesDefault() + { + var m = _container.Resolve>(); + Assert.Equal((int)42, (int)m.Metadata.TheInt); } } diff --git a/test/Autofac.Integration.Mef.Test/TestTypes/IMeta.cs b/test/Autofac.Integration.Mef.Test/TestTypes/IMeta.cs index dac26f0..cd4483e 100644 --- a/test/Autofac.Integration.Mef.Test/TestTypes/IMeta.cs +++ b/test/Autofac.Integration.Mef.Test/TestTypes/IMeta.cs @@ -1,10 +1,9 @@ // Copyright (c) Autofac Project. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -namespace Autofac.Integration.Mef.Test.TestTypes +namespace Autofac.Integration.Mef.Test.TestTypes; + +public interface IMeta { - public interface IMeta - { - int TheInt { get; } - } + int TheInt { get; } } diff --git a/test/Autofac.Integration.Mef.Test/TestTypes/IMetaWithDefault.cs b/test/Autofac.Integration.Mef.Test/TestTypes/IMetaWithDefault.cs index eea3598..8231213 100644 --- a/test/Autofac.Integration.Mef.Test/TestTypes/IMetaWithDefault.cs +++ b/test/Autofac.Integration.Mef.Test/TestTypes/IMetaWithDefault.cs @@ -3,11 +3,10 @@ using System.ComponentModel; -namespace Autofac.Integration.Mef.Test.TestTypes +namespace Autofac.Integration.Mef.Test.TestTypes; + +public interface IMetaWithDefault { - public interface IMetaWithDefault - { - [DefaultValue(42)] - int TheInt { get; } - } + [DefaultValue(42)] + int TheInt { get; } } diff --git a/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs b/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs index 1f20169..19946a6 100644 --- a/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs +++ b/test/Autofac.Integration.Mef.Test/TestTypes/MetaAttribute.cs @@ -3,14 +3,13 @@ using System.ComponentModel.Composition; -namespace Autofac.Integration.Mef.Test.TestTypes +namespace Autofac.Integration.Mef.Test.TestTypes; + +[MetadataAttribute] +[AttributeUsage(AttributeTargets.Class)] +public sealed class MetaAttribute : Attribute, IMeta { - [MetadataAttribute] - [AttributeUsage(AttributeTargets.Class)] - public sealed class MetaAttribute : Attribute, IMeta - { - public MetaAttribute(int theInt) => TheInt = theInt; + public MetaAttribute(int theInt) => TheInt = theInt; - public int TheInt { get; private set; } - } + public int TheInt { get; private set; } } From e2d97c6e134f000571e5eb57293cf4af956c746c Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:29:48 -0700 Subject: [PATCH 12/20] Ignore file-scoped namespace commit in blame. --- .git-blame-ignore-revs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..b05fb9c --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,11 @@ +# Ignore revisions in git blame - set your git config to use the file by convention: +# git config --global blame.ignoreRevsFile .git-blame-ignore-revs +# +# Optional additional git config: +# Mark any lines that have had a commit skipped using --ignore-rev with a `?` +# git config --global blame.markIgnoredLines true +# Mark any lines that were added in a skipped commit and can not be attributed with a `*` +# git config --global blame.markUnblamableLines true + +# Convert to file-scoped namespaces. +55e222d88b289465dec967979b7e481849306c21 From 2a5f08f3a9b0a2c5eafe181f626374c981c24673 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:31:24 -0700 Subject: [PATCH 13/20] Name can be simplified. --- src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs | 2 +- .../LazyWithMetadataRegistrationSource.cs | 2 +- src/Autofac.Integration.Mef/RegistrationExtensions.cs | 4 ++-- src/Autofac.Integration.Mef/Util/TypeExtensions.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs b/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs index 74ce26c..2cbf5de 100644 --- a/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs +++ b/src/Autofac.Integration.Mef/ExportConfigurationBuilder.cs @@ -108,7 +108,7 @@ public ExportConfigurationBuilder WithMetadata(string key, object value) /// /// Metadata. /// Builder for additional configuration. - /// + /// /// Thrown if is . /// public ExportConfigurationBuilder WithMetadata(IEnumerable> metadata) diff --git a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs b/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs index cb905f0..168c44f 100644 --- a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs +++ b/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSource.cs @@ -10,7 +10,7 @@ namespace Autofac.Integration.Mef; /// -/// Support the +/// Support the /// types automatically whenever type T is registered with the container. /// /// diff --git a/src/Autofac.Integration.Mef/RegistrationExtensions.cs b/src/Autofac.Integration.Mef/RegistrationExtensions.cs index f7b9ff7..8ec0a0b 100644 --- a/src/Autofac.Integration.Mef/RegistrationExtensions.cs +++ b/src/Autofac.Integration.Mef/RegistrationExtensions.cs @@ -22,14 +22,14 @@ namespace Autofac.Integration.Mef; public static class RegistrationExtensions { /// - /// Reference to the internal for System.ComponentModel.Composition.ContractNameServices, + /// Reference to the internal for System.ComponentModel.Composition.ContractNameServices, /// which is responsible for mapping types to MEF contract names. /// private static readonly Type ContractNameServices = typeof(ExportAttribute).Assembly.GetType("System.ComponentModel.Composition.ContractNameServices", true); /// /// Reference to the property System.ComponentModel.Composition.ContractNameServices.TypeIdentityCache, - /// which holds the dictionary of to contract name mappings. + /// which holds the dictionary of to contract name mappings. /// private static readonly PropertyInfo TypeIdentityCache = ContractNameServices.GetProperty("TypeIdentityCache", BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.NonPublic); diff --git a/src/Autofac.Integration.Mef/Util/TypeExtensions.cs b/src/Autofac.Integration.Mef/Util/TypeExtensions.cs index afc353a..69ecade 100644 --- a/src/Autofac.Integration.Mef/Util/TypeExtensions.cs +++ b/src/Autofac.Integration.Mef/Util/TypeExtensions.cs @@ -4,7 +4,7 @@ namespace Autofac.Integration.Mef.Util; /// -/// Extension methods for working with . +/// Extension methods for working with . /// internal static class TypeExtensions { From 894c771d88377adc06763cac2a95794361ba5637 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:35:24 -0700 Subject: [PATCH 14/20] Simplify if statement. --- src/Autofac.Integration.Mef/RegistrationExtensions.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Autofac.Integration.Mef/RegistrationExtensions.cs b/src/Autofac.Integration.Mef/RegistrationExtensions.cs index 8ec0a0b..30f47c4 100644 --- a/src/Autofac.Integration.Mef/RegistrationExtensions.cs +++ b/src/Autofac.Integration.Mef/RegistrationExtensions.cs @@ -493,14 +493,7 @@ private static bool TryGetLazyType(this ContractBasedImportDefinition definition .GetGenericTypeDefinition() .MakeGenericType(objectType, typeof(IDictionary)); - if (!isLazy) - { - resultType = typeof(IEnumerable<>).MakeGenericType(lazyType); - } - else - { - resultType = lazyType; - } + resultType = isLazy ? lazyType : typeof(IEnumerable<>).MakeGenericType(lazyType); return true; } From b3c2a831643e5b76747af14d0b227e0d6bf5fba1 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:36:35 -0700 Subject: [PATCH 15/20] Use pattern matching. --- src/Autofac.Integration.Mef/RegistrationExtensions.cs | 2 +- src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Autofac.Integration.Mef/RegistrationExtensions.cs b/src/Autofac.Integration.Mef/RegistrationExtensions.cs index 30f47c4..55c8919 100644 --- a/src/Autofac.Integration.Mef/RegistrationExtensions.cs +++ b/src/Autofac.Integration.Mef/RegistrationExtensions.cs @@ -548,7 +548,7 @@ private static void SetImports(IComponentContext context, ComposablePart composa .ImportDefinitions .Where(id => id.IsPrerequisite == prerequisite)) { - if (!(import is ContractBasedImportDefinition definition)) + if (import is not ContractBasedImportDefinition definition) { throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, RegistrationExtensionsResources.ContractBasedOnly, import)); } diff --git a/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs b/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs index aee992d..7cad660 100644 --- a/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs +++ b/src/Autofac.Integration.Mef/Util/ReflectionExtensions.cs @@ -49,7 +49,7 @@ public static PropertyInfo GetProperty( } var mex = propertyAccessor.Body as MemberExpression; - if (!(mex?.Member is PropertyInfo)) + if (mex?.Member is not PropertyInfo) { throw new ArgumentException(string.Format( CultureInfo.CurrentCulture, From 9b4641af38ac8d8589dd803d345e5f7e5d42e92f Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:37:33 -0700 Subject: [PATCH 16/20] Removed redundant cast. --- .../StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs | 6 +++--- ...glyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs index 075b22c..6d2246e 100644 --- a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenMetadataIsSuppliedTests.cs @@ -24,20 +24,20 @@ public StronglyTypedMetadataWhenMetadataIsSuppliedTests() public void ValuesAreProvidedFromMetadata() { var meta = _container.Resolve>(); - Assert.Equal((int)SuppliedValue, (int)meta.Metadata.TheInt); + Assert.Equal(SuppliedValue, meta.Metadata.TheInt); } [Fact] public void ValuesProvidedFromMetadataOverrideDefaults() { var meta = _container.Resolve>(); - Assert.Equal((int)SuppliedValue, (int)meta.Metadata.TheInt); + Assert.Equal(SuppliedValue, meta.Metadata.TheInt); } [Fact] public void ValuesBubbleUpThroughAdapters() { var meta = _container.Resolve, IMeta>>(); - Assert.Equal((int)SuppliedValue, (int)meta.Metadata.TheInt); + Assert.Equal(SuppliedValue, meta.Metadata.TheInt); } } diff --git a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs index 289521a..d937cb9 100644 --- a/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/StronglyTypedMetadataWhenNoMatchingMetadataIsSuppliedTests.cs @@ -31,6 +31,6 @@ public void ResolvingStronglyTypedMetadataWithoutDefaultValueThrowsException() public void ResolvingStronglyTypedMetadataWithDefaultValueProvidesDefault() { var m = _container.Resolve>(); - Assert.Equal((int)42, (int)m.Metadata.TheInt); + Assert.Equal(42, m.Metadata.TheInt); } } From 538d1ee063b34eb87938fdf2557f3f4c32dbdfcf Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 21 Sep 2022 10:38:10 -0700 Subject: [PATCH 17/20] Fix formatting. --- .../LazyWithMetadataWhenMetadataIsSuppliedTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs index 1a572d3..aab7227 100644 --- a/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs +++ b/test/Autofac.Integration.Mef.Test/LazyWithMetadataWhenMetadataIsSuppliedTests.cs @@ -117,7 +117,7 @@ internal class ServiceConsumer internal class ServiceConsumerFromParameters { [ImportingConstructor] - public ServiceConsumerFromParameters([ImportMany]IEnumerable> services) + public ServiceConsumerFromParameters([ImportMany] IEnumerable> services) { Services = services; } From 755a7c85caa4cfc38e66441dc828dd105d29d407 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Fri, 30 Sep 2022 06:47:08 -0700 Subject: [PATCH 18/20] Remove generated designer files. --- .../ContractBasedServiceResources.Designer.cs | 69 ------------------- ...ataRegistrationSourceResources.Designer.cs | 69 ------------------- ...ataRegistrationSourceResources.Designer.cs | 69 ------------------- .../ReflectionExtensionsResources.Designer.cs | 69 ------------------- 4 files changed, 276 deletions(-) delete mode 100644 src/Autofac.Integration.Mef/ContractBasedServiceResources.Designer.cs delete mode 100644 src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSourceResources.Designer.cs delete mode 100644 src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSourceResources.Designer.cs delete mode 100644 src/Autofac.Integration.Mef/Util/ReflectionExtensionsResources.Designer.cs diff --git a/src/Autofac.Integration.Mef/ContractBasedServiceResources.Designer.cs b/src/Autofac.Integration.Mef/ContractBasedServiceResources.Designer.cs deleted file mode 100644 index 3f38683..0000000 --- a/src/Autofac.Integration.Mef/ContractBasedServiceResources.Designer.cs +++ /dev/null @@ -1,69 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Autofac.Integration.Mef { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// This class was generated by MSBuild using the GenerateResource task. - /// To add or remove a member, edit your .resx file then rerun MSBuild. - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class ContractBasedServiceResources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal ContractBasedServiceResources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Autofac.Integration.Mef.ContractBasedServiceResources", typeof(ContractBasedServiceResources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to ContractName={0}. - /// - internal static string DescriptionFormat { - get { - return ResourceManager.GetString("DescriptionFormat", resourceCulture); - } - } - } -} diff --git a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSourceResources.Designer.cs b/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSourceResources.Designer.cs deleted file mode 100644 index 3989646..0000000 --- a/src/Autofac.Integration.Mef/LazyWithMetadataRegistrationSourceResources.Designer.cs +++ /dev/null @@ -1,69 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Autofac.Integration.Mef { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// This class was generated by MSBuild using the GenerateResource task. - /// To add or remove a member, edit your .resx file then rerun MSBuild. - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class LazyWithMetadataRegistrationSourceResources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal LazyWithMetadataRegistrationSourceResources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Autofac.Integration.Mef.LazyWithMetadataRegistrationSourceResources", typeof(LazyWithMetadataRegistrationSourceResources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Lazy<T, TMetadata> Support. - /// - internal static string LazyWithMetadataRegistrationSourceDescription { - get { - return ResourceManager.GetString("LazyWithMetadataRegistrationSourceDescription", resourceCulture); - } - } - } -} diff --git a/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSourceResources.Designer.cs b/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSourceResources.Designer.cs deleted file mode 100644 index 52a66a9..0000000 --- a/src/Autofac.Integration.Mef/StronglyTypedMetadataRegistrationSourceResources.Designer.cs +++ /dev/null @@ -1,69 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Autofac.Integration.Mef { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// This class was generated by MSBuild using the GenerateResource task. - /// To add or remove a member, edit your .resx file then rerun MSBuild. - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class StronglyTypedMetadataRegistrationSourceResources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal StronglyTypedMetadataRegistrationSourceResources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Autofac.Integration.Mef.StronglyTypedMetadataRegistrationSourceResources", typeof(StronglyTypedMetadataRegistrationSourceResources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Meta<T, TMetadata> Support. - /// - internal static string StronglyTypedMetaRegistrationSourceDescription { - get { - return ResourceManager.GetString("StronglyTypedMetaRegistrationSourceDescription", resourceCulture); - } - } - } -} diff --git a/src/Autofac.Integration.Mef/Util/ReflectionExtensionsResources.Designer.cs b/src/Autofac.Integration.Mef/Util/ReflectionExtensionsResources.Designer.cs deleted file mode 100644 index fa1506e..0000000 --- a/src/Autofac.Integration.Mef/Util/ReflectionExtensionsResources.Designer.cs +++ /dev/null @@ -1,69 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Autofac.Integration.Mef.Util { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// This class was generated by MSBuild using the GenerateResource task. - /// To add or remove a member, edit your .resx file then rerun MSBuild. - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class ReflectionExtensionsResources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal ReflectionExtensionsResources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Autofac.Integration.Mef.Util.ReflectionExtensionsResources", typeof(ReflectionExtensionsResources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to The provided expression must be of the form x =>x.P, but the provided expression was {0}.. - /// - internal static string ExpressionNotPropertyAccessor { - get { - return ResourceManager.GetString("ExpressionNotPropertyAccessor", resourceCulture); - } - } - } -} From ec65233aa99090e61af4142f795841f8f66ed8e6 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Fri, 30 Sep 2022 06:48:18 -0700 Subject: [PATCH 19/20] Ignore generated designer files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 78f36f7..7d9e4cf 100644 --- a/.gitignore +++ b/.gitignore @@ -139,6 +139,7 @@ node_modules/ bower_components/ wwwroot/ project.lock.json +*.Designer.cs # RIA/Silverlight projects Generated_Code/ From 11f768b579c5fe2cd3087254cbf409a3449a5189 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Fri, 30 Sep 2022 06:51:48 -0700 Subject: [PATCH 20/20] Enable designer file nesting for resx in VS Code. --- .vscode/settings.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 927073a..8ad744f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,9 @@ "xunit" ], "dotnet-test-explorer.testProjectPath": "test/**/*Test.csproj", + "explorer.fileNesting.patterns": { + "*.resx": "$(capture).*.resx, $(capture).Designer.cs" + }, "omnisharp.enableEditorConfigSupport": true, "omnisharp.enableRoslynAnalyzers": true }