diff --git a/.editorconfig b/.editorconfig
index 2920f1f..57b2d5a 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,8 +1,5 @@
-; EditorConfig to support per-solution formatting.
-; Use the EditorConfig VS add-in to make this work.
-; http://editorconfig.org/
-
-; This is the default for the codeline.
+# EditorConfig to support per-solution formatting.
+# http://editorconfig.org/
root = true
[*]
@@ -10,13 +7,187 @@ indent_style = space
trim_trailing_whitespace = true
insert_final_newline = true
-; .NET Code - almost, but not exactly, the same suggestions as corefx
-; https://github.com/dotnet/corefx/blob/master/.editorconfig
+# .NET Code
[*.cs]
indent_size = 4
charset = utf-8-bom
-; New line preferences
+# .NET project files and MSBuild - match defaults for VS
+[*.{csproj,nuspec,proj,projitems,props,shproj,targets,vbproj,vcxproj,vcxproj.filters,vsixmanifest,vsct}]
+indent_size = 2
+
+# .NET solution files - match defaults for VS
+[*.sln]
+end_of_line = crlf
+indent_style = tab
+
+# .NET XML solution files - match dotnet new sln defaults
+[*.slnx]
+indent_size = 2
+
+
+# Config - match XML and default nuget.config template
+[*.config]
+indent_size = 2
+
+# Resources - match defaults for VS
+[*.resx]
+indent_size = 2
+
+# Static analysis rulesets - match defaults for VS
+[*.ruleset]
+indent_size = 2
+
+# HTML, XML - match defaults for VS
+[*.{cshtml,html,xml}]
+indent_size = 4
+
+# JavaScript and JS mixes - match eslint settings; JSON also matches .NET Core templates
+[*.{js,json,mjs,ts,vue}]
+indent_size = 2
+
+# Markdown - match markdownlint settings
+[*.{md,markdown}]
+indent_size = 2
+
+# PowerShell - match defaults for New-ModuleManifest and PSScriptAnalyzer Invoke-Formatter
+[*.{ps1,psd1,psm1}]
+indent_size = 4
+charset = utf-8-bom
+
+# YAML - match standard YAML like Kubernetes and GitHub Actions
+[*.{yaml,yml}]
+indent_size = 2
+
+# ReStructuredText - standard indentation format from examples
+[*.rst]
+indent_size = 2
+
+#
+# dotnet code style
+#
+[*.cs]
+
+# Sort using and Import directives with System.* appearing first
+dotnet_sort_system_directives_first = true
+dotnet_separate_import_directive_groups = false
+
+# Avoid this. unless absolutely necessary
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+
+# Use language keywords instead of framework type names for type references
+dotnet_style_predefined_type_for_locals_parameters_members = true:warning
+dotnet_style_predefined_type_for_member_access = true:warning
+
+# Suggest more modern language features when available
+dotnet_style_object_initializer = true:warning
+dotnet_style_collection_initializer = true:warning
+dotnet_style_coalesce_expression = true:warning
+dotnet_style_null_propagation = true:warning
+dotnet_style_explicit_tuple_names = true:warning
+
+# Whitespace options
+dotnet_style_allow_multiple_blank_lines_experimental = false
+
+# Non-private static fields are PascalCase
+dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = warning
+dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields
+dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style
+
+dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field
+dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
+dotnet_naming_symbols.non_private_static_fields.required_modifiers = static
+
+dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case
+
+# Non-private readonly fields are PascalCase
+dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.severity = warning
+dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.symbols = non_private_readonly_fields
+dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.style = non_private_readonly_field_style
+
+dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field
+dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
+dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly
+
+dotnet_naming_style.non_private_readonly_field_style.capitalization = pascal_case
+
+# Constants are PascalCase
+dotnet_naming_rule.constants_should_be_pascal_case.severity = warning
+dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants
+dotnet_naming_rule.constants_should_be_pascal_case.style = constant_style
+
+dotnet_naming_symbols.constants.applicable_kinds = field, local
+dotnet_naming_symbols.constants.required_modifiers = const
+
+dotnet_naming_style.constant_style.capitalization = pascal_case
+
+# Static fields should be _camelCase
+dotnet_naming_rule.static_fields_should_be_camel_case.severity = warning
+dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields
+dotnet_naming_rule.static_fields_should_be_camel_case.style = camel_case_underscore_style
+dotnet_naming_symbols.static_fields.applicable_kinds = field
+dotnet_naming_symbols.static_fields.required_modifiers = static
+
+dotnet_naming_style.static_field_style.capitalization = camel_case
+
+# Instance fields are camelCase and start with _
+dotnet_naming_rule.instance_fields_should_be_camel_case.severity = warning
+dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields
+dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style
+
+dotnet_naming_symbols.instance_fields.applicable_kinds = field
+
+dotnet_naming_style.instance_field_style.capitalization = camel_case
+dotnet_naming_style.instance_field_style.required_prefix = _
+
+# Locals and parameters are camelCase
+dotnet_naming_rule.locals_should_be_camel_case.severity = warning
+dotnet_naming_rule.locals_should_be_camel_case.symbols = locals_and_parameters
+dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style
+
+dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local
+
+dotnet_naming_style.camel_case_style.capitalization = camel_case
+
+# Local functions are PascalCase
+dotnet_naming_rule.local_functions_should_be_pascal_case.severity = warning
+dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions
+dotnet_naming_rule.local_functions_should_be_pascal_case.style = local_function_style
+
+dotnet_naming_symbols.local_functions.applicable_kinds = local_function
+
+dotnet_naming_style.local_function_style.capitalization = pascal_case
+
+# By default, name items with PascalCase
+dotnet_naming_rule.members_should_be_pascal_case.severity = warning
+dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members
+dotnet_naming_rule.members_should_be_pascal_case.style = pascal_case_style
+
+dotnet_naming_symbols.all_members.applicable_kinds = *
+
+dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+
+# IDE0035: Remove unreachable code
+dotnet_diagnostic.IDE0035.severity = warning
+
+# IDE0036: Order modifiers
+dotnet_diagnostic.IDE0036.severity = warning
+
+# IDE0043: Format string contains invalid placeholder
+dotnet_diagnostic.IDE0043.severity = warning
+
+# IDE0044: Make field readonly
+dotnet_diagnostic.IDE0044.severity = warning
+
+# IDE0055: Fix formatting
+dotnet_diagnostic.IDE0055.severity = warning
+
+# C# code style
+#
+# Newline settings
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
@@ -25,90 +196,34 @@ csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
-; Indentation preferences
+# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_switch_labels = true
-csharp_indent_labels = one_less_than_current
+csharp_indent_labels = flush_left
-; Modifier preferences
-csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
+# Whitespace options
+# Each of the *_experimental rules has a corresponding IDE* setting.
+csharp_style_allow_embedded_statements_on_same_line_experimental = false
+dotnet_diagnostic.IDE2001.severity = warning
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
+dotnet_diagnostic.IDE2002.severity = warning
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
+dotnet_diagnostic.IDE2004.severity = warning
+csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false
+dotnet_diagnostic.IDE2005.severity = warning
+csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false
+dotnet_diagnostic.IDE2006.severity = warning
-; Avoid this. unless absolutely necessary
-dotnet_style_qualification_for_field = false:suggestion
-dotnet_style_qualification_for_property = false:suggestion
-dotnet_style_qualification_for_method = false:suggestion
-dotnet_style_qualification_for_event = false:suggestion
-
-; Types: use keywords instead of BCL types, using var is fine.
-csharp_style_var_when_type_is_apparent = false:none
-dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
-dotnet_style_predefined_type_for_member_access = true:suggestion
-
-; Name all constant fields using PascalCase
-dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
-dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
-dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
-dotnet_naming_symbols.constant_fields.applicable_kinds = field
-dotnet_naming_symbols.constant_fields.required_modifiers = const
-dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+# Prefer "var" everywhere
+dotnet_diagnostic.IDE0007.severity = warning
+csharp_style_var_for_built_in_types = true:warning
+csharp_style_var_when_type_is_apparent = true:warning
+csharp_style_var_elsewhere = true:warning
-; 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.symbols = static_fields
-dotnet_naming_rule.static_fields_should_be_camel_case.style = camel_case_underscore_style
-dotnet_naming_symbols.static_fields.applicable_kinds = field
-dotnet_naming_symbols.static_fields.required_modifiers = static
-dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
-
-; Static readonly fields should be PascalCase
-dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.severity = suggestion
-dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.symbols = static_readonly_fields
-dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.style = pascal_case_style
-dotnet_naming_symbols.static_readonly_fields.applicable_kinds = field
-dotnet_naming_symbols.static_readonly_fields.required_modifiers = static, readonly
-dotnet_naming_symbols.static_readonly_fields.applicable_accessibilities = private, internal, private_protected
-
-; Internal and private fields should be _camelCase
-dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
-dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
-dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
-dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
-dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
-dotnet_naming_style.camel_case_underscore_style.required_prefix = _
-dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
-
-; Code style defaults
-csharp_using_directive_placement = outside_namespace:suggestion
-dotnet_sort_system_directives_first = true
-csharp_prefer_braces = true:refactoring
-csharp_preserve_single_line_blocks = true:none
-csharp_preserve_single_line_statements = false:none
-csharp_prefer_static_local_function = true:suggestion
-csharp_prefer_simple_using_statement = false:none
-csharp_style_prefer_switch_expression = true:suggestion
-
-; Code quality
-dotnet_style_readonly_field = true:suggestion
-dotnet_code_quality_unused_parameters = non_public:suggestion
-
-; Expression-level preferences
-dotnet_style_object_initializer = true:suggestion
-dotnet_style_collection_initializer = true:suggestion
-dotnet_style_explicit_tuple_names = true:suggestion
-dotnet_style_coalesce_expression = true:suggestion
-dotnet_style_null_propagation = true:suggestion
-dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
-dotnet_style_prefer_inferred_tuple_names = true:suggestion
-dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
-dotnet_style_prefer_auto_properties = true:suggestion
-dotnet_style_prefer_conditional_expression_over_assignment = true:refactoring
-dotnet_style_prefer_conditional_expression_over_return = true:refactoring
-csharp_prefer_simple_default_expression = true:suggestion
-
-# Expression-bodied members
+# Prefer method-like constructs to have a block body
csharp_style_expression_bodied_methods = true:refactoring
csharp_style_expression_bodied_constructors = true:refactoring
csharp_style_expression_bodied_operators = true:refactoring
@@ -118,19 +233,15 @@ csharp_style_expression_bodied_accessors = true:refactoring
csharp_style_expression_bodied_lambdas = true:refactoring
csharp_style_expression_bodied_local_functions = true:refactoring
-# Pattern matching
-csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
-csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
-csharp_style_inlined_variable_declaration = true:suggestion
-
-# Null checking preferences
-csharp_style_throw_expression = true:suggestion
-csharp_style_conditional_delegate_call = true:suggestion
-
-# Other features
-csharp_style_prefer_index_operator = false:none
-csharp_style_prefer_range_operator = false:none
-csharp_style_pattern_local_over_anonymous_function = false:none
+# Suggest more modern language features when available
+csharp_style_pattern_matching_over_is_with_cast_check = true:warning
+csharp_style_pattern_matching_over_as_with_null_check = true:warning
+csharp_style_inlined_variable_declaration = true:warning
+csharp_style_throw_expression = true:warning
+csharp_style_conditional_delegate_call = true:warning
+csharp_style_prefer_extended_property_pattern = true:warning
+csharp_style_namespace_declarations = file_scoped:warning
+csharp_style_prefer_parameter_null_checking = false
# Space preferences
csharp_space_after_cast = false
@@ -156,43 +267,30 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
-; .NET project files and MSBuild - match defaults for VS
-[*.{csproj,nuspec,proj,projitems,props,shproj,targets,vbproj,vcxproj,vcxproj.filters,vsixmanifest,vsct}]
-indent_size = 2
+# Blocks required
+csharp_prefer_braces = true:warning
+csharp_preserve_single_line_blocks = false
+csharp_preserve_single_line_statements = false
-; .NET solution files - match defaults for VS
-[*.sln]
-indent_style = tab
+# IDE0011: Add braces
+csharp_prefer_braces = when_multiline:warning
+# NOTE: We need the below severity entry for Add Braces due to https://github.com/dotnet/roslyn/issues/44201
+dotnet_diagnostic.IDE0011.severity = warning
-; Config - match XML and default nuget.config template
-[*.config]
-indent_size = 2
+# IDE0040: Add accessibility modifiers
+dotnet_diagnostic.IDE0040.severity = warning
-; Resources - match defaults for VS
-[*.resx]
-indent_size = 2
+# IDE0052: Remove unread private member
+dotnet_diagnostic.IDE0052.severity = warning
-; Static analysis rulesets - match defaults for VS
-[*.ruleset]
-indent_size = 2
-
-; HTML, XML - match defaults for VS
-[*.{cshtml,html,xml}]
-indent_size = 4
-
-; JavaScript and JS mixes - match eslint settings; JSON also matches .NET Core templates
-[*.{js,json,ts,vue}]
-indent_size = 2
+# IDE0059: Unnecessary assignment to a value
+dotnet_diagnostic.IDE0059.severity = warning
-; Markdown - match markdownlint settings
-[*.{md,markdown}]
-indent_size = 2
+# IDE0060: Remove unused parameter
+dotnet_diagnostic.IDE0060.severity = warning
-; PowerShell - match defaults for New-ModuleManifest and PSScriptAnalyzer Invoke-Formatter
-[*.{ps1,psd1,psm1}]
-indent_size = 4
-charset = utf-8-bom
+# CA1012: Abstract types should not have public constructors
+dotnet_diagnostic.CA1012.severity = warning
-; ReStructuredText - standard indentation format from examples
-[*.rst]
-indent_size = 2
+# CA1822: Make member static
+dotnet_diagnostic.CA1822.severity = warning
diff --git a/build/Source.ruleset b/build/Source.ruleset
index d76a694..459e4e0 100644
--- a/build/Source.ruleset
+++ b/build/Source.ruleset
@@ -4,23 +4,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
+
-
+
-
+
-
-
-
+
diff --git a/build/Test.ruleset b/build/Test.ruleset
index b9bb945..3c26c01 100644
--- a/build/Test.ruleset
+++ b/build/Test.ruleset
@@ -1,51 +1,92 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
diff --git a/build/stylecop.json b/build/stylecop.json
index 8f5c703..20da2f6 100644
--- a/build/stylecop.json
+++ b/build/stylecop.json
@@ -9,6 +9,9 @@
"licenseName": "MIT"
},
"xmlHeader": false
+ },
+ "orderingRules": {
+ "usingDirectivesPlacement": "outsideNamespace"
}
}
}
diff --git a/default.proj b/default.proj
index 6764a54..f4bce04 100644
--- a/default.proj
+++ b/default.proj
@@ -57,8 +57,8 @@
-
-
+
+
diff --git a/src/Autofac.Extras.AggregateService/AggregateServiceGenerator.cs b/src/Autofac.Extras.AggregateService/AggregateServiceGenerator.cs
index 7ce0efa..1caa0a8 100644
--- a/src/Autofac.Extras.AggregateService/AggregateServiceGenerator.cs
+++ b/src/Autofac.Extras.AggregateService/AggregateServiceGenerator.cs
@@ -5,53 +5,52 @@
using System.Reflection;
using Castle.DynamicProxy;
-namespace Autofac.Extras.AggregateService
+namespace Autofac.Extras.AggregateService;
+
+///
+/// Generate aggregate service instances from interface types.
+///
+public static class AggregateServiceGenerator
{
+ private static readonly ProxyGenerator _generator = new ProxyGenerator();
+
///
- /// Generate aggregate service instances from interface types.
+ /// Generate an aggregate service instance that will resolve its types from .
///
- public static class AggregateServiceGenerator
+ /// The component context from where types will be resolved.
+ /// The interface type for the aggregate service.
+ /// The aggregate service instance.
+ /// Thrown if is not an interface.
+ public static object CreateInstance(IComponentContext context)
{
- private static readonly ProxyGenerator Generator = new ProxyGenerator();
-
- ///
- /// Generate an aggregate service instance that will resolve its types from .
- ///
- /// The component context from where types will be resolved.
- /// The interface type for the aggregate service.
- /// The aggregate service instance.
- /// Thrown if is not an interface.
- public static object CreateInstance(IComponentContext context)
+ return CreateInstance(typeof(TAggregateServiceInterface), context);
+ }
+
+ ///
+ /// Generate an aggregate service instance that will resolve its types from .
+ ///
+ /// The interface type for the aggregate service.
+ /// The component context from where types will be resolved.
+ /// The aggregate service instance.
+ /// Thrown if is not an interface.
+ public static object CreateInstance(Type interfaceType, IComponentContext context)
+ {
+ if (context == null)
{
- return CreateInstance(typeof(TAggregateServiceInterface), context);
+ throw new ArgumentNullException(nameof(context));
}
- ///
- /// Generate an aggregate service instance that will resolve its types from .
- ///
- /// The interface type for the aggregate service.
- /// The component context from where types will be resolved.
- /// The aggregate service instance.
- /// Thrown if is not an interface.
- public static object CreateInstance(Type interfaceType, IComponentContext context)
+ if (interfaceType == null)
{
- if (context == null)
- {
- throw new ArgumentNullException(nameof(context));
- }
-
- if (interfaceType == null)
- {
- throw new ArgumentNullException(nameof(interfaceType));
- }
-
- if (!interfaceType.GetTypeInfo().IsInterface)
- {
- throw new ArgumentException(AggregateServicesResources.TypeMustBeInterface, nameof(interfaceType));
- }
-
- var resolverInterceptor = new ResolvingInterceptor(interfaceType, context);
- return Generator.CreateInterfaceProxyWithoutTarget(interfaceType, resolverInterceptor);
+ throw new ArgumentNullException(nameof(interfaceType));
}
+
+ if (!interfaceType.GetTypeInfo().IsInterface)
+ {
+ throw new ArgumentException(AggregateServicesResources.TypeMustBeInterface, nameof(interfaceType));
+ }
+
+ var resolverInterceptor = new ResolvingInterceptor(interfaceType, context);
+ return _generator.CreateInterfaceProxyWithoutTarget(interfaceType, resolverInterceptor);
}
}
diff --git a/src/Autofac.Extras.AggregateService/ContainerBuilderExtensions.cs b/src/Autofac.Extras.AggregateService/ContainerBuilderExtensions.cs
index fd98336..d7cdb21 100644
--- a/src/Autofac.Extras.AggregateService/ContainerBuilderExtensions.cs
+++ b/src/Autofac.Extras.AggregateService/ContainerBuilderExtensions.cs
@@ -4,72 +4,71 @@
using System;
using System.Reflection;
-namespace Autofac.Extras.AggregateService
+namespace Autofac.Extras.AggregateService;
+
+///
+/// AggregateService extensions to .
+///
+public static class ContainerBuilderExtensions
{
///
- /// AggregateService extensions to .
+ /// Register as an aggregate service.
+ ///
+ /// The container builder.
+ /// The interface type to register.
+ /// If is null.
+ /// If is not an interface.
+ public static void RegisterAggregateService(this ContainerBuilder builder)
+ where TInterface : class
+ {
+ builder.RegisterAggregateService(typeof(TInterface));
+ }
+
+ ///
+ /// Register as an aggregate service.
///
- public static class ContainerBuilderExtensions
+ /// The container builder.
+ /// The interface type to register.
+ /// If is null.
+ /// If is not an interface.
+ public static void RegisterAggregateService(this ContainerBuilder builder, Type interfaceType)
{
- ///
- /// Register as an aggregate service.
- ///
- /// The container builder.
- /// The interface type to register.
- /// If is null.
- /// If is not an interface.
- public static void RegisterAggregateService(this ContainerBuilder builder)
- where TInterface : class
+ if (interfaceType == null)
{
- builder.RegisterAggregateService(typeof(TInterface));
+ throw new ArgumentNullException(nameof(interfaceType));
}
- ///
- /// Register as an aggregate service.
- ///
- /// The container builder.
- /// The interface type to register.
- /// If is null.
- /// If is not an interface.
- public static void RegisterAggregateService(this ContainerBuilder builder, Type interfaceType)
+ if (!interfaceType.GetTypeInfo().IsInterface)
{
- if (interfaceType == null)
- {
- throw new ArgumentNullException(nameof(interfaceType));
- }
-
- if (!interfaceType.GetTypeInfo().IsInterface)
- {
- throw new ArgumentException(AggregateServicesResources.TypeMustBeInterface, nameof(interfaceType));
- }
+ throw new ArgumentException(AggregateServicesResources.TypeMustBeInterface, nameof(interfaceType));
+ }
- if (interfaceType.IsGenericTypeDefinition)
+ if (interfaceType.IsGenericTypeDefinition)
+ {
+ RegisterAggregateServiceAsOpenGeneric(builder, interfaceType);
+ }
+ else
+ {
+ if (interfaceType.ContainsGenericParameters)
{
- RegisterAggregateServiceAsOpenGeneric(builder, interfaceType);
+ throw new ArgumentException(AggregateServicesResources.InterfaceMayNotContainGenericParameters, nameof(interfaceType));
}
- else
- {
- if (interfaceType.ContainsGenericParameters)
- {
- throw new ArgumentException(AggregateServicesResources.InterfaceMayNotContainGenericParameters, nameof(interfaceType));
- }
- RegisterAggregateServiceAsInstance(builder, interfaceType);
- }
+ RegisterAggregateServiceAsInstance(builder, interfaceType);
}
+ }
- private static void RegisterAggregateServiceAsInstance(ContainerBuilder builder, Type interfaceType) =>
- builder.Register(c =>
- AggregateServiceGenerator.CreateInstance(interfaceType, c.Resolve()))
- .As(interfaceType)
- .InstancePerDependency();
+ private static void RegisterAggregateServiceAsInstance(ContainerBuilder builder, Type interfaceType)
+ => builder.Register(c =>
+ AggregateServiceGenerator.CreateInstance(interfaceType, c.Resolve()))
+ .As(interfaceType)
+ .InstancePerDependency();
- private static void RegisterAggregateServiceAsOpenGeneric(ContainerBuilder builder, Type interfaceType) =>
- builder.RegisterGeneric((c, types) =>
- AggregateServiceGenerator.CreateInstance(
- interfaceType.MakeGenericType(types),
- c.Resolve()))
- .As(interfaceType)
- .InstancePerDependency();
- }
+ private static void RegisterAggregateServiceAsOpenGeneric(ContainerBuilder builder, Type interfaceType)
+ => builder.RegisterGeneric((c, types) =>
+ AggregateServiceGenerator.CreateInstance(
+ interfaceType.MakeGenericType(types),
+ c.Resolve()))
+ .As(interfaceType)
+ .InstancePerDependency();
}
diff --git a/src/Autofac.Extras.AggregateService/ResolvingInterceptor.cs b/src/Autofac.Extras.AggregateService/ResolvingInterceptor.cs
index 31f8195..a769f95 100644
--- a/src/Autofac.Extras.AggregateService/ResolvingInterceptor.cs
+++ b/src/Autofac.Extras.AggregateService/ResolvingInterceptor.cs
@@ -10,165 +10,160 @@
using Autofac.Core;
using Castle.DynamicProxy;
-namespace Autofac.Extras.AggregateService
+namespace Autofac.Extras.AggregateService;
+
+///
+/// Interceptor that resolves types of properties and methods using a .
+///
+public class ResolvingInterceptor : IInterceptor
{
+ private static readonly Assembly _systemAssembly = typeof(Func<>).Assembly;
+
+ private readonly IComponentContext _context;
+
+ private readonly Dictionary> _invocationMap;
+
///
- /// Interceptor that resolves types of properties and methods using a .
+ /// Initializes a new instance of the class.
///
- public class ResolvingInterceptor : IInterceptor
+ /// Type of the interface to intercept.
+ /// The resolution context.
+ public ResolvingInterceptor(Type interfaceType, IComponentContext context)
{
- private static readonly Assembly SystemAssembly = typeof(Func<>).Assembly;
-
- private readonly IComponentContext _context;
-
- private readonly Dictionary> _invocationMap;
+ _context = context;
+ _invocationMap = SetupInvocationMap(interfaceType);
+ }
- ///
- /// Initializes a new instance of the class.
- ///
- /// Type of the interface to intercept.
- /// The resolution context.
- public ResolvingInterceptor(Type interfaceType, IComponentContext context)
+ ///
+ /// Intercepts a method invocation.
+ ///
+ ///
+ /// The method invocation to intercept.
+ ///
+ public void Intercept(IInvocation invocation)
+ {
+ if (invocation == null)
{
- _context = context;
- _invocationMap = SetupInvocationMap(interfaceType);
+ throw new ArgumentNullException(nameof(invocation));
}
- ///
- /// Intercepts a method invocation.
- ///
- ///
- /// The method invocation to intercept.
- ///
- public void Intercept(IInvocation invocation)
- {
- if (invocation == null)
- {
- throw new ArgumentNullException(nameof(invocation));
- }
+ // Generic methods need to use the open generic method definition.
+ var method = invocation.Method.IsGenericMethod ? invocation.Method.GetGenericMethodDefinition() : invocation.Method;
+ var invocationHandler = _invocationMap[method];
+ invocationHandler(invocation);
+ }
- // Generic methods need to use the open generic method definition.
- var method = invocation.Method.IsGenericMethod ? invocation.Method.GetGenericMethodDefinition() : invocation.Method;
- var invocationHandler = _invocationMap[method];
- invocationHandler(invocation);
- }
+ private static PropertyInfo? GetProperty(MethodInfo method)
+ {
+ var takesArg = method.GetParameters().Length == 1;
+ var hasReturn = method.ReturnType != typeof(void);
- private static PropertyInfo? GetProperty(MethodInfo method)
+ if (takesArg == hasReturn)
{
- var takesArg = method.GetParameters().Length == 1;
- var hasReturn = method.ReturnType != typeof(void);
+ return null;
+ }
- if (takesArg == hasReturn)
- {
- return null;
- }
+ return method
+ .DeclaringType
+ .GetProperties()
+ .Where(prop => prop.GetGetMethod() == method)
+ .FirstOrDefault();
+ }
- return method
- .DeclaringType
- .GetProperties()
- .Where(prop => prop.GetGetMethod() == method)
- .FirstOrDefault();
- }
+ private static void InvalidReturnTypeInvocation(IInvocation invocation)
+ {
+ throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The method {0} has invalid return type System.Void", invocation.Method));
+ }
- private static void InvalidReturnTypeInvocation(IInvocation invocation)
- {
- throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The method {0} has invalid return type System.Void", invocation.Method));
- }
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This method gets called via reflection.")]
+ [SuppressMessage("Microsoft.Performance", "IDE0051", Justification = "This method gets called via reflection.")]
+ private void MethodWithoutParams(IInvocation invocation)
+ {
+ // To handle open generics, this resolves the return type of the invocation rather than the scanned method.
+ invocation.ReturnValue = _context.Resolve(invocation.Method.ReturnType);
+ }
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This method gets called via reflection.")]
- [SuppressMessage("Microsoft.Performance", "IDE0051", Justification = "This method gets called via reflection.")]
- private void MethodWithoutParams(IInvocation invocation)
- {
- // To handle open generics, this resolves the return type of the invocation rather than the scanned method.
- invocation.ReturnValue = _context.Resolve(invocation.Method.ReturnType);
- }
+ private Dictionary> SetupInvocationMap(Type interfaceType)
+ {
+ var methods = interfaceType
+ .GetUniqueInterfaces()
+ .SelectMany(x => x.GetMethods())
+ .ToArray();
- private Dictionary> SetupInvocationMap(Type interfaceType)
+ var methodMap = new Dictionary>(methods.Length);
+ foreach (var method in methods)
{
- var methods = interfaceType
- .GetUniqueInterfaces()
- .SelectMany(x => x.GetMethods())
- .ToArray();
+ var returnType = method.ReturnType;
- var methodMap = new Dictionary>(methods.Length);
- foreach (var method in methods)
+ if (returnType == typeof(void))
{
- var returnType = method.ReturnType;
+ // Any method with 'void' return type (includes property setters) should throw an exception
+ methodMap.Add(method, InvalidReturnTypeInvocation);
+ continue;
+ }
- if (returnType == typeof(void))
- {
- // Any method with 'void' return type (includes property setters) should throw an exception
- methodMap.Add(method, InvalidReturnTypeInvocation);
- continue;
- }
+ if (GetProperty(method) != null)
+ {
+ // All properties should be resolved at proxy instantiation
+ var propertyValue = _context.Resolve(returnType);
+ methodMap.Add(method, invocation => invocation.ReturnValue = propertyValue);
+ continue;
+ }
+
+ // For methods with parameters, cache parameter info for use at invocation time
+ var parameters = method.GetParameters()
+ .OrderBy(parameterInfo => parameterInfo.Position)
+ .Select(parameterInfo => new { parameterInfo.Position, parameterInfo.ParameterType })
+ .ToArray();
- if (GetProperty(method) != null)
+ if (parameters.Length > 0)
+ {
+ // Methods with parameters
+ if (parameters.Any(p => p.ParameterType.IsGenericType))
{
- // All properties should be resolved at proxy instantiation
- var propertyValue = _context.Resolve(returnType);
- methodMap.Add(method, invocation => invocation.ReturnValue = propertyValue);
- continue;
+ // There are some open generic parameters so resolve a
+ // Func corresponding to the method parameters and
+ // method return type. Core Autofac will handle the type
+ // mapping from open generic to closed generic, etc.
+ methodMap.Add(
+ method,
+ invocation =>
+ {
+ var targetMethod = invocation.Method;
+ var funcArgTypes = targetMethod.GetParameters().OrderBy(p => p.Position).Select(p => p.ParameterType).Append(targetMethod.ReturnType).ToArray();
+ var funcTypeName = $"System.Func`{funcArgTypes.Length}";
+ var baseFuncType = _systemAssembly.GetType(funcTypeName) ?? throw new NotSupportedException($"Unable to locate function type for dynamic resolution: {funcTypeName}. Ensure your method doesn't have too many parameters to convert to a System.Func delegate.");
+
+ var builtFuncType = baseFuncType.MakeGenericType(funcArgTypes);
+ var factory = (Delegate)_context.Resolve(builtFuncType);
+ invocation.ReturnValue = factory!.DynamicInvoke(invocation.Arguments);
+ });
}
-
- // For methods with parameters, cache parameter info for use at invocation time
- var parameters = method.GetParameters()
- .OrderBy(parameterInfo => parameterInfo.Position)
- .Select(parameterInfo => new { parameterInfo.Position, parameterInfo.ParameterType })
- .ToArray();
-
- if (parameters.Length > 0)
+ else
{
- // Methods with parameters
- if (parameters.Any(p => p.ParameterType.IsGenericType))
- {
- // There are some open generic parameters so resolve a
- // Func corresponding to the method parameters and
- // method return type. Core Autofac will handle the type
- // mapping from open generic to closed generic, etc.
- methodMap.Add(
- method,
- invocation =>
- {
- var targetMethod = invocation.Method;
- var funcArgTypes = targetMethod.GetParameters().OrderBy(p => p.Position).Select(p => p.ParameterType).Append(targetMethod.ReturnType).ToArray();
- var funcTypeName = $"System.Func`{funcArgTypes.Length}";
- var baseFuncType = SystemAssembly.GetType(funcTypeName);
- if (baseFuncType == null)
- {
- throw new NotSupportedException($"Unable to locate function type for dynamic resolution: {funcTypeName}. Ensure your method doesn't have too many parameters to convert to a System.Func delegate.");
- }
-
- var builtFuncType = baseFuncType.MakeGenericType(funcArgTypes);
- var factory = (Delegate)_context.Resolve(builtFuncType);
- invocation.ReturnValue = factory!.DynamicInvoke(invocation.Arguments);
- });
- }
- else
- {
- // There are no open generic parameters so we can simplify the backing method.
- methodMap.Add(
- method,
- invocation =>
- {
- var arguments = invocation.Arguments;
- var typedParameters = parameters
- .Select(info => (Parameter)new TypedParameter(info.ParameterType, arguments[info.Position]));
-
- // To handle open generics, this resolves the return type of the invocation rather than the scanned method.
- invocation.ReturnValue = _context.Resolve(invocation.Method.ReturnType, typedParameters);
- });
- }
-
- continue;
+ // There are no open generic parameters so we can simplify the backing method.
+ methodMap.Add(
+ method,
+ invocation =>
+ {
+ var arguments = invocation.Arguments;
+ var typedParameters = parameters
+ .Select(info => (Parameter)new TypedParameter(info.ParameterType, arguments[info.Position]));
+
+ // To handle open generics, this resolves the return type of the invocation rather than the scanned method.
+ invocation.ReturnValue = _context.Resolve(invocation.Method.ReturnType, typedParameters);
+ });
}
- // Methods without parameters
- var methodWithoutParams = GetType().GetMethod("MethodWithoutParams", BindingFlags.Instance | BindingFlags.NonPublic);
- var methodWithoutParamsDelegate = (Action)methodWithoutParams.CreateDelegate(typeof(Action), this);
- methodMap.Add(method, methodWithoutParamsDelegate);
+ continue;
}
- return methodMap;
+ // Methods without parameters
+ var methodWithoutParams = GetType().GetMethod("MethodWithoutParams", BindingFlags.Instance | BindingFlags.NonPublic);
+ var methodWithoutParamsDelegate = (Action)methodWithoutParams.CreateDelegate(typeof(Action), this);
+ methodMap.Add(method, methodWithoutParamsDelegate);
}
+
+ return methodMap;
}
}
diff --git a/src/Autofac.Extras.AggregateService/TypeExtensions.cs b/src/Autofac.Extras.AggregateService/TypeExtensions.cs
index be438cc..3479316 100644
--- a/src/Autofac.Extras.AggregateService/TypeExtensions.cs
+++ b/src/Autofac.Extras.AggregateService/TypeExtensions.cs
@@ -5,42 +5,41 @@
using System.Collections.Generic;
using System.Reflection;
-namespace Autofac.Extras.AggregateService
+namespace Autofac.Extras.AggregateService;
+
+///
+/// Extension methods for working with .
+///
+internal static class TypeExtensions
{
///
- /// Extension methods for working with .
+ /// Return unique interfaces implemented or inherited by .
+ /// Will also include if it is an interface type.
///
- internal static class TypeExtensions
+ ///
+ /// The type for which interfaces should be retrieved.
+ ///
+ ///
+ /// A list of unique interfaces implemented by the provided type.
+ ///
+ public static IEnumerable GetUniqueInterfaces(this Type type)
{
- ///
- /// Return unique interfaces implemented or inherited by .
- /// Will also include if it is an interface type.
- ///
- ///
- /// The type for which interfaces should be retrieved.
- ///
- ///
- /// A list of unique interfaces implemented by the provided type.
- ///
- public static IEnumerable GetUniqueInterfaces(this Type type)
+ var types = new HashSet();
+ foreach (var interfaceType in type.GetInterfaces())
{
- var types = new HashSet();
- foreach (var interfaceType in type.GetInterfaces())
+ if (types.Contains(interfaceType))
{
- if (types.Contains(interfaceType))
- {
- continue;
- }
-
- types.Add(interfaceType);
+ continue;
}
- if (type.GetTypeInfo().IsInterface && !types.Contains(type))
- {
- types.Add(type);
- }
+ types.Add(interfaceType);
+ }
- return types;
+ if (type.GetTypeInfo().IsInterface && !types.Contains(type))
+ {
+ types.Add(type);
}
+
+ return types;
}
}
diff --git a/test/Autofac.Extras.AggregateService.Test/AggregateServiceFixture.cs b/test/Autofac.Extras.AggregateService.Test/AggregateServiceFixture.cs
index 6dcef75..6d04c0c 100644
--- a/test/Autofac.Extras.AggregateService.Test/AggregateServiceFixture.cs
+++ b/test/Autofac.Extras.AggregateService.Test/AggregateServiceFixture.cs
@@ -5,101 +5,100 @@
using NSubstitute;
using Xunit;
-namespace Autofac.Extras.AggregateService.Test
+namespace Autofac.Extras.AggregateService.Test;
+
+public class AggregateServiceFixture
{
- public class AggregateServiceFixture
+ private readonly IContainer _container;
+
+ private readonly ISomeDependency _someDependencyMock;
+
+ private readonly IMyContext _aggregateService;
+
+ public AggregateServiceFixture()
+ {
+ _someDependencyMock = Substitute.For();
+
+ var builder = new ContainerBuilder();
+ builder.RegisterAggregateService();
+ builder.RegisterType()
+ .As()
+ .InstancePerDependency();
+ builder.RegisterInstance(_someDependencyMock);
+ _container = builder.Build();
+
+ _aggregateService = _container.Resolve();
+ }
+
+ [Fact]
+ public void Property_ResolvesService()
+ {
+ var service = _aggregateService.MyService;
+ Assert.NotNull(service);
+ Assert.IsAssignableFrom(service);
+ }
+
+ [Fact]
+ public void Property_Getter_AlwaysReturnSameInstance()
+ {
+ var firstInstance = _aggregateService.MyService;
+ var secondInstance = _aggregateService.MyService;
+
+ Assert.Same(secondInstance, firstInstance);
+ }
+
+ [Fact]
+ public void Property_Setter_Throws()
+ {
+ Assert.Throws(() => _aggregateService.PropertyWithSetter = null);
+ }
+
+ [Fact]
+ public void Method_WithVoid_Throws()
{
- private readonly IContainer _container;
-
- private readonly ISomeDependency _someDependencyMock;
-
- private readonly IMyContext _aggregateService;
-
- public AggregateServiceFixture()
- {
- _someDependencyMock = Substitute.For();
-
- var builder = new ContainerBuilder();
- builder.RegisterAggregateService();
- builder.RegisterType()
- .As()
- .InstancePerDependency();
- builder.RegisterInstance(_someDependencyMock);
- _container = builder.Build();
-
- _aggregateService = _container.Resolve();
- }
-
- [Fact]
- public void Property_ResolvesService()
- {
- var service = _aggregateService.MyService;
- Assert.NotNull(service);
- Assert.IsAssignableFrom(service);
- }
-
- [Fact]
- public void Property_Getter_AlwaysReturnSameInstance()
- {
- var firstInstance = _aggregateService.MyService;
- var secondInstance = _aggregateService.MyService;
-
- Assert.Same(secondInstance, firstInstance);
- }
-
- [Fact]
- public void Property_Setter_Throws()
- {
- Assert.Throws(() => _aggregateService.PropertyWithSetter = null);
- }
-
- [Fact]
- public void Method_WithVoid_Throws()
- {
- Assert.Throws(() => _aggregateService.MethodWithoutReturnValue());
- }
-
- [Fact]
- public void Method_ResolvesService()
- {
- var service = _aggregateService.GetMyService();
- Assert.NotNull(service);
- Assert.IsAssignableFrom(service);
- }
-
- [Fact]
- public void Method_WithParameter_PassesParameterToService()
- {
- var myService = _aggregateService.GetMyService(10);
-
- Assert.Equal(10, myService.SomeIntValue);
- }
-
- [Fact]
- public void Method_WithParameters_PassesParametersToService()
- {
- var someDate = DateTime.Now;
- var myService = _aggregateService.GetMyService(someDate, 20);
-
- Assert.Equal(someDate, myService.SomeDateValue);
- Assert.Equal(20, myService.SomeIntValue);
- }
-
- [Fact]
- public void Method_WithNullParameters_PassesParametersToService()
- {
- var myService = _aggregateService.GetMyService(null);
-
- Assert.Null(myService.SomeStringValue);
- }
-
- [Fact]
- public void Method_WithParameter_PassesParameterAndOtherDependenciesToService()
- {
- var myService = _aggregateService.GetMyService("text");
-
- Assert.Equal("text", myService.SomeStringValue);
- Assert.Equal(_someDependencyMock, myService.SomeDependency);
- }
+ Assert.Throws(() => _aggregateService.MethodWithoutReturnValue());
+ }
+
+ [Fact]
+ public void Method_ResolvesService()
+ {
+ var service = _aggregateService.GetMyService();
+ Assert.NotNull(service);
+ Assert.IsAssignableFrom(service);
+ }
+
+ [Fact]
+ public void Method_WithParameter_PassesParameterToService()
+ {
+ var myService = _aggregateService.GetMyService(10);
+
+ Assert.Equal(10, myService.SomeIntValue);
+ }
+
+ [Fact]
+ public void Method_WithParameters_PassesParametersToService()
+ {
+ var someDate = DateTime.Now;
+ var myService = _aggregateService.GetMyService(someDate, 20);
+
+ Assert.Equal(someDate, myService.SomeDateValue);
+ Assert.Equal(20, myService.SomeIntValue);
+ }
+
+ [Fact]
+ public void Method_WithNullParameters_PassesParametersToService()
+ {
+ var myService = _aggregateService.GetMyService(null);
+
+ Assert.Null(myService.SomeStringValue);
+ }
+
+ [Fact]
+ public void Method_WithParameter_PassesParameterAndOtherDependenciesToService()
+ {
+ var myService = _aggregateService.GetMyService("text");
+
+ Assert.Equal("text", myService.SomeStringValue);
+ Assert.Equal(_someDependencyMock, myService.SomeDependency);
}
}
diff --git a/test/Autofac.Extras.AggregateService.Test/AggregateServiceGeneratorFixture.cs b/test/Autofac.Extras.AggregateService.Test/AggregateServiceGeneratorFixture.cs
index 05f2c3f..b20e10b 100644
--- a/test/Autofac.Extras.AggregateService.Test/AggregateServiceGeneratorFixture.cs
+++ b/test/Autofac.Extras.AggregateService.Test/AggregateServiceGeneratorFixture.cs
@@ -5,51 +5,50 @@
using NSubstitute;
using Xunit;
-namespace Autofac.Extras.AggregateService.Test
+namespace Autofac.Extras.AggregateService.Test;
+
+public class AggregateServiceGeneratorFixture
{
- public class AggregateServiceGeneratorFixture
+ private readonly IContainer _container;
+
+ public AggregateServiceGeneratorFixture()
+ {
+ var builder = new ContainerBuilder();
+ builder.RegisterInstance(Substitute.For());
+ _container = builder.Build();
+ }
+
+ [Fact]
+ public void CreateInstance_WithGenericInterface_CreatesInstanceOfInterface()
+ {
+ var instance = AggregateServiceGenerator.CreateInstance(_container);
+
+ Assert.IsAssignableFrom(instance);
+ }
+
+ [Fact]
+ public void CreateInstance_WithInterfaceType_CreatesInstanceOfInterface()
+ {
+ var instance = AggregateServiceGenerator.CreateInstance(typeof(IMyContext), _container);
+
+ Assert.IsAssignableFrom(instance);
+ }
+
+ [Fact]
+ public void CreateInstance_ExpectsInterfaceTypeInstance()
+ {
+ Assert.Throws(() => AggregateServiceGenerator.CreateInstance(null, _container));
+ }
+
+ [Fact]
+ public void CreateInstance_ExpectsComponentInstance()
+ {
+ Assert.Throws(() => AggregateServiceGenerator.CreateInstance(typeof(IMyContext), null));
+ }
+
+ [Fact]
+ public void CreateInstance_ExpectsInterfaceType()
{
- private readonly IContainer _container;
-
- public AggregateServiceGeneratorFixture()
- {
- var builder = new ContainerBuilder();
- builder.RegisterInstance(Substitute.For());
- _container = builder.Build();
- }
-
- [Fact]
- public void CreateInstance_WithGenericInterface_CreatesInstanceOfInterface()
- {
- var instance = AggregateServiceGenerator.CreateInstance(_container);
-
- Assert.IsAssignableFrom(instance);
- }
-
- [Fact]
- public void CreateInstance_WithInterfaceType_CreatesInstanceOfInterface()
- {
- var instance = AggregateServiceGenerator.CreateInstance(typeof(IMyContext), _container);
-
- Assert.IsAssignableFrom(instance);
- }
-
- [Fact]
- public void CreateInstance_ExpectsInterfaceTypeInstance()
- {
- Assert.Throws(() => AggregateServiceGenerator.CreateInstance(null, _container));
- }
-
- [Fact]
- public void CreateInstance_ExpectsComponentInstance()
- {
- Assert.Throws(() => AggregateServiceGenerator.CreateInstance(typeof(IMyContext), null));
- }
-
- [Fact]
- public void CreateInstance_ExpectsInterfaceType()
- {
- Assert.Throws(() => AggregateServiceGenerator.CreateInstance(_container));
- }
+ Assert.Throws(() => AggregateServiceGenerator.CreateInstance(_container));
}
}
diff --git a/test/Autofac.Extras.AggregateService.Test/AggregateServiceGenericsFixture.cs b/test/Autofac.Extras.AggregateService.Test/AggregateServiceGenericsFixture.cs
index 7a3d8e5..9250fc0 100644
--- a/test/Autofac.Extras.AggregateService.Test/AggregateServiceGenericsFixture.cs
+++ b/test/Autofac.Extras.AggregateService.Test/AggregateServiceGenericsFixture.cs
@@ -4,63 +4,62 @@
using System;
using Xunit;
-namespace Autofac.Extras.AggregateService.Test
+namespace Autofac.Extras.AggregateService.Test;
+
+public class AggregateServiceGenericsFixture
{
- public class AggregateServiceGenericsFixture
- {
- private readonly IContainer _container;
+ private readonly IContainer _container;
- public AggregateServiceGenericsFixture()
- {
- var builder = new ContainerBuilder();
- builder.RegisterAggregateService();
- builder.RegisterGeneric(typeof(OpenGenericImpl<>))
- .As(typeof(IOpenGeneric<>));
- builder.RegisterGeneric(typeof(PassThroughOpenGenericImpl<>))
- .As(typeof(IPassThroughOpenGeneric<>));
+ public AggregateServiceGenericsFixture()
+ {
+ var builder = new ContainerBuilder();
+ builder.RegisterAggregateService();
+ builder.RegisterGeneric(typeof(OpenGenericImpl<>))
+ .As(typeof(IOpenGeneric<>));
+ builder.RegisterGeneric(typeof(PassThroughOpenGenericImpl<>))
+ .As(typeof(IPassThroughOpenGeneric<>));
- _container = builder.Build();
- }
+ _container = builder.Build();
+ }
- ///
- /// Attempts to resolve an open generic by a method call.
- ///
- [Fact]
- public void Method_ResolveOpenGeneric()
- {
- var aggregateService = _container.Resolve();
+ ///
+ /// Attempts to resolve an open generic by a method call.
+ ///
+ [Fact]
+ public void Method_ResolveOpenGeneric()
+ {
+ var aggregateService = _container.Resolve();
- var generic = aggregateService.GetOpenGeneric