diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..23c94c9
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,166 @@
+# To learn more about .editorconfig see https://aka.ms/editorconfigdocs
+###############################
+# Core EditorConfig Options #
+###############################
+# All files
+[*]
+indent_style = space
+
+# XML project files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
+indent_size = 2
+
+# XML config files
+[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
+indent_size = 2
+
+# Code files
+[*.{cs,csx,vb,vbx}]
+indent_size = 4
+insert_final_newline = true
+charset = utf-8-bom
+###############################
+# .NET Coding Conventions #
+###############################
+[*.{cs,vb}]
+# Organize usings
+dotnet_sort_system_directives_first = true
+# this. preferences
+dotnet_style_qualification_for_field = true:error
+dotnet_style_qualification_for_property = true:error
+dotnet_style_qualification_for_method = true:error
+dotnet_style_qualification_for_event = true:error
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true:silent
+dotnet_style_predefined_type_for_member_access = true:silent
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
+dotnet_style_readonly_field = true: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_null_propagation = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+###############################
+# Naming Conventions #
+###############################
+# Style Definitions
+dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+# Use PascalCase for constant fields
+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.applicable_accessibilities = *
+dotnet_naming_symbols.constant_fields.required_modifiers = const
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+tab_width = 4
+end_of_line = crlf
+dotnet_style_prefer_compound_assignment = true:suggestion
+dotnet_style_prefer_simplified_interpolation = true:suggestion
+dotnet_style_namespace_match_folder = true:suggestion
+dotnet_style_allow_multiple_blank_lines_experimental = true:silent
+dotnet_style_allow_statement_immediately_after_block_experimental = false:suggestion
+dotnet_code_quality_unused_parameters = all:error
+###############################
+# C# Coding Conventions #
+###############################
+[*.cs]
+# var preferences
+csharp_style_var_for_built_in_types = true:silent
+csharp_style_var_when_type_is_apparent = true:silent
+csharp_style_var_elsewhere = true:silent
+# Expression-bodied members
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_accessors = true:silent
+# Pattern matching preferences
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+# Null-checking preferences
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+# Modifier preferences
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
+# Expression-level preferences
+csharp_prefer_braces = true:silent
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_pattern_local_over_anonymous_function = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+###############################
+# C# Formatting Rules #
+###############################
+# New line preferences
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+# Indentation preferences
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = flush_left
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+# Wrapping preferences
+csharp_preserve_single_line_statements = true
+csharp_preserve_single_line_blocks = true
+csharp_using_directive_placement = outside_namespace:error
+csharp_prefer_simple_using_statement = true:error
+csharp_style_namespace_declarations = file_scoped:error
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+csharp_indent_braces = false
+csharp_style_prefer_null_check_over_type_check = true:suggestion
+csharp_style_prefer_local_over_anonymous_function = true:error
+csharp_style_prefer_index_operator = true:suggestion
+csharp_style_prefer_range_operator = true:suggestion
+csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
+csharp_style_prefer_tuple_swap = true:suggestion
+csharp_style_unused_value_assignment_preference = discard_variable:error
+csharp_style_unused_value_expression_statement_preference = discard_variable:silent
+csharp_prefer_static_local_function = true:suggestion
+csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:suggestion
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
+csharp_style_prefer_parameter_null_checking = true:suggestion
+csharp_style_prefer_switch_expression = true:suggestion
+csharp_style_prefer_pattern_matching = true:silent
+csharp_style_prefer_not_pattern = true:suggestion
+csharp_style_prefer_extended_property_pattern = true:suggestion
+###############################
+# VB Coding Conventions #
+###############################
+[*.vb]
+# Modifier preferences
+visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
diff --git a/Slim.Integration/Slim.Integration.csproj b/Slim.Integration/Slim.Integration.csproj
new file mode 100644
index 0000000..a3089af
--- /dev/null
+++ b/Slim.Integration/Slim.Integration.csproj
@@ -0,0 +1,25 @@
+
+
+
+ netstandard2.0
+ true
+ latest
+ Alexandru Macocian
+
+
+ Integration with Microsoft.DependencyInjection library.
+ 1.0.0
+ 1.0.0
+ https://github.com/AlexMacocian/Slim
+ 1.0.0
+ true
+ true
+ LICENSE
+
+
+
+
+
+
+
+
diff --git a/Slim.Tests/MemoryLeakTests.cs b/Slim.Tests/MemoryLeakTests.cs
index 8a5b7ab..ae5c51e 100644
--- a/Slim.Tests/MemoryLeakTests.cs
+++ b/Slim.Tests/MemoryLeakTests.cs
@@ -4,42 +4,41 @@ using Slim.Tests.Models;
using System;
using System.Threading.Tasks;
-namespace Slim.Tests
+namespace Slim.Tests;
+
+[TestClass]
+public sealed class MemoryLeakTests
{
- [TestClass]
- public sealed class MemoryLeakTests
+ private const int ScopesCount = 10000;
+
+ [TestMethod]
+ public async Task CreateAndReleaseScopesDisposeManagerGCCollects()
{
- private const int ScopesCount = 10000;
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterScoped();
+ var independentService = di.GetService();
+ var dependentService = di.GetService();
- [TestMethod]
- public async Task CreateAndReleaseScopesDisposeManagerGCCollects()
+ var weakRefs = new WeakReference[ScopesCount];
+ for (int i = 0; i < ScopesCount; i++)
{
- var di = new ServiceManager();
- di.RegisterSingleton();
- di.RegisterScoped();
- var independentService = di.GetService();
- var dependentService = di.GetService();
+ var scopedDi = di.CreateScope();
+ weakRefs[i] = new WeakReference(scopedDi);
+ var scopedDependentService = scopedDi.GetService();
+ scopedDependentService.Should().NotBeNull();
+ scopedDependentService.Should().NotBe(dependentService);
+ scopedDependentService.IndependentService.Should().NotBeNull();
+ scopedDependentService.IndependentService.Should().Be(independentService);
+ }
- var weakRefs = new WeakReference[ScopesCount];
- for (int i = 0; i < ScopesCount; i++)
- {
- var scopedDi = di.CreateScope();
- weakRefs[i] = new WeakReference(scopedDi);
- var scopedDependentService = scopedDi.GetService();
- scopedDependentService.Should().NotBeNull();
- scopedDependentService.Should().NotBe(dependentService);
- scopedDependentService.IndependentService.Should().NotBeNull();
- scopedDependentService.IndependentService.Should().Be(independentService);
- }
-
- await Task.Delay(1500);
- GC.Collect();
- GC.WaitForPendingFinalizers();
- GC.Collect();
- foreach(var weakRef in weakRefs)
- {
- weakRef.IsAlive.Should().BeFalse();
- }
+ await Task.Delay(1500);
+ GC.Collect();
+ GC.WaitForPendingFinalizers();
+ GC.Collect();
+ foreach (var weakRef in weakRefs)
+ {
+ weakRef.IsAlive.Should().BeFalse();
}
}
}
diff --git a/Slim.Tests/Models/DependentOnPrivateCtrService.cs b/Slim.Tests/Models/DependentOnPrivateCtrService.cs
index f09e222..d084b94 100644
--- a/Slim.Tests/Models/DependentOnPrivateCtrService.cs
+++ b/Slim.Tests/Models/DependentOnPrivateCtrService.cs
@@ -1,13 +1,12 @@
-namespace Slim.Tests.Models
-{
- public sealed class DependentOnPrivateCtrService : IDependentOnPrivateCtrService
- {
- private readonly IPrivateConstructorService privateConstructorService;
+namespace Slim.Tests.Models;
- public DependentOnPrivateCtrService(
- IPrivateConstructorService privateConstructorService)
- {
- this.privateConstructorService = privateConstructorService;
- }
+public sealed class DependentOnPrivateCtrService : IDependentOnPrivateCtrService
+{
+ private readonly IPrivateConstructorService privateConstructorService;
+
+ public DependentOnPrivateCtrService(
+ IPrivateConstructorService privateConstructorService)
+ {
+ this.privateConstructorService = privateConstructorService;
}
}
diff --git a/Slim.Tests/Models/DependentOnServiceManagerService.cs b/Slim.Tests/Models/DependentOnServiceManagerService.cs
index c91e273..e3be426 100644
--- a/Slim.Tests/Models/DependentOnServiceManagerService.cs
+++ b/Slim.Tests/Models/DependentOnServiceManagerService.cs
@@ -1,19 +1,18 @@
-namespace Slim.Tests.Models
-{
- public class DependentOnServiceManagerService : IDependentOnServiceManagerService
- {
- public IServiceManager ServiceManager { get; }
- public IServiceProducer ServiceProducer { get; }
- public IServiceProvider ServiceProvider { get; }
+namespace Slim.Tests.Models;
- public DependentOnServiceManagerService(
- IServiceManager serviceManager,
- IServiceProvider serviceProvider,
- IServiceProducer serviceProducer)
- {
- this.ServiceManager = serviceManager;
- this.ServiceProvider = serviceProvider;
- this.ServiceProducer = serviceProducer;
- }
+public class DependentOnServiceManagerService : IDependentOnServiceManagerService
+{
+ public IServiceManager ServiceManager { get; }
+ public IServiceProducer ServiceProducer { get; }
+ public IServiceProvider ServiceProvider { get; }
+
+ public DependentOnServiceManagerService(
+ IServiceManager serviceManager,
+ IServiceProvider serviceProvider,
+ IServiceProducer serviceProducer)
+ {
+ this.ServiceManager = serviceManager;
+ this.ServiceProvider = serviceProvider;
+ this.ServiceProducer = serviceProducer;
}
}
diff --git a/Slim.Tests/Models/DependentOnThrowingService.cs b/Slim.Tests/Models/DependentOnThrowingService.cs
index 26f6b24..cf2095c 100644
--- a/Slim.Tests/Models/DependentOnThrowingService.cs
+++ b/Slim.Tests/Models/DependentOnThrowingService.cs
@@ -1,12 +1,11 @@
-namespace Slim.Tests.Models
-{
- public sealed class DependentOnThrowingService : IDependentOnThrowingService
- {
- private readonly IThrowingService throwingService;
+namespace Slim.Tests.Models;
- public DependentOnThrowingService(IThrowingService throwingService)
- {
- this.throwingService = throwingService;
- }
+public sealed class DependentOnThrowingService : IDependentOnThrowingService
+{
+ private readonly IThrowingService throwingService;
+
+ public DependentOnThrowingService(IThrowingService throwingService)
+ {
+ this.throwingService = throwingService;
}
}
diff --git a/Slim.Tests/Models/DependentService.cs b/Slim.Tests/Models/DependentService.cs
index e06d01c..ab39182 100644
--- a/Slim.Tests/Models/DependentService.cs
+++ b/Slim.Tests/Models/DependentService.cs
@@ -1,12 +1,11 @@
-namespace Slim.Tests.Models
-{
- public class DependentService : IDependentService
- {
- public DependentService(IIndependentService independentService)
- {
- this.IndependentService = independentService;
- }
+namespace Slim.Tests.Models;
- public IIndependentService IndependentService { get; }
+public class DependentService : IDependentService
+{
+ public DependentService(IIndependentService independentService)
+ {
+ this.IndependentService = independentService;
}
+
+ public IIndependentService IndependentService { get; }
}
diff --git a/Slim.Tests/Models/DependentService2.cs b/Slim.Tests/Models/DependentService2.cs
index 4339803..e294161 100644
--- a/Slim.Tests/Models/DependentService2.cs
+++ b/Slim.Tests/Models/DependentService2.cs
@@ -1,12 +1,11 @@
-namespace Slim.Tests.Models
-{
- public sealed class DependentService2 : IDependentService2
- {
- public IndependentService IndependentService { get; }
+namespace Slim.Tests.Models;
- public DependentService2(IndependentService independentService)
- {
- this.IndependentService = independentService;
- }
+public sealed class DependentService2 : IDependentService2
+{
+ public IndependentService IndependentService { get; }
+
+ public DependentService2(IndependentService independentService)
+ {
+ this.IndependentService = independentService;
}
}
diff --git a/Slim.Tests/Models/DoNotInjectConstructorService.cs b/Slim.Tests/Models/DoNotInjectConstructorService.cs
index 9637c9b..065fa04 100644
--- a/Slim.Tests/Models/DoNotInjectConstructorService.cs
+++ b/Slim.Tests/Models/DoNotInjectConstructorService.cs
@@ -1,12 +1,11 @@
using Slim.Attributes;
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public sealed class DoNotInjectConstructorService
{
- public sealed class DoNotInjectConstructorService
+ [DoNotInject]
+ public DoNotInjectConstructorService()
{
- [DoNotInject]
- public DoNotInjectConstructorService()
- {
- }
}
}
diff --git a/Slim.Tests/Models/IDependentOnPrivateCtrService.cs b/Slim.Tests/Models/IDependentOnPrivateCtrService.cs
index ff503b6..5fe9348 100644
--- a/Slim.Tests/Models/IDependentOnPrivateCtrService.cs
+++ b/Slim.Tests/Models/IDependentOnPrivateCtrService.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IDependentOnPrivateCtrService
{
- public interface IDependentOnPrivateCtrService
- {
- }
}
diff --git a/Slim.Tests/Models/IDependentOnServiceManagerService.cs b/Slim.Tests/Models/IDependentOnServiceManagerService.cs
index c8fad13..ca8ce15 100644
--- a/Slim.Tests/Models/IDependentOnServiceManagerService.cs
+++ b/Slim.Tests/Models/IDependentOnServiceManagerService.cs
@@ -1,9 +1,8 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IDependentOnServiceManagerService
{
- public interface IDependentOnServiceManagerService
- {
- IServiceManager ServiceManager { get; }
- IServiceProducer ServiceProducer { get; }
- IServiceProvider ServiceProvider { get; }
- }
+ IServiceManager ServiceManager { get; }
+ IServiceProducer ServiceProducer { get; }
+ IServiceProvider ServiceProvider { get; }
}
diff --git a/Slim.Tests/Models/IDependentOnThrowingService.cs b/Slim.Tests/Models/IDependentOnThrowingService.cs
index c955b48..6eacd43 100644
--- a/Slim.Tests/Models/IDependentOnThrowingService.cs
+++ b/Slim.Tests/Models/IDependentOnThrowingService.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IDependentOnThrowingService
{
- public interface IDependentOnThrowingService
- {
- }
}
diff --git a/Slim.Tests/Models/IDependentService.cs b/Slim.Tests/Models/IDependentService.cs
index d1d9646..70a084e 100644
--- a/Slim.Tests/Models/IDependentService.cs
+++ b/Slim.Tests/Models/IDependentService.cs
@@ -1,7 +1,6 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IDependentService
{
- public interface IDependentService
- {
- IIndependentService IndependentService { get; }
- }
+ IIndependentService IndependentService { get; }
}
diff --git a/Slim.Tests/Models/IDependentService2.cs b/Slim.Tests/Models/IDependentService2.cs
index 853082b..d8871f7 100644
--- a/Slim.Tests/Models/IDependentService2.cs
+++ b/Slim.Tests/Models/IDependentService2.cs
@@ -1,7 +1,6 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IDependentService2
{
- public interface IDependentService2
- {
- public IndependentService IndependentService { get; }
- }
+ public IndependentService IndependentService { get; }
}
diff --git a/Slim.Tests/Models/IDisposableService.cs b/Slim.Tests/Models/IDisposableService.cs
index 1fb6956..b5a2f27 100644
--- a/Slim.Tests/Models/IDisposableService.cs
+++ b/Slim.Tests/Models/IDisposableService.cs
@@ -1,12 +1,11 @@
-namespace Slim.Tests.Models
-{
- public class IDisposableService : IIDisposableService
- {
- public bool DisposeCalled { get; set; }
+namespace Slim.Tests.Models;
- public void Dispose()
- {
- this.DisposeCalled = true;
- }
+public class IDisposableService : IIDisposableService
+{
+ public bool DisposeCalled { get; set; }
+
+ public void Dispose()
+ {
+ this.DisposeCalled = true;
}
}
diff --git a/Slim.Tests/Models/IDisposableSingletonService.cs b/Slim.Tests/Models/IDisposableSingletonService.cs
index db68e2c..4e57171 100644
--- a/Slim.Tests/Models/IDisposableSingletonService.cs
+++ b/Slim.Tests/Models/IDisposableSingletonService.cs
@@ -1,12 +1,11 @@
-namespace Slim.Tests.Models
-{
- public sealed class IDisposableSingletonService : IIDisposableService
- {
- public bool DisposeCalled { get; set; }
+namespace Slim.Tests.Models;
- public void Dispose()
- {
- this.DisposeCalled = true;
- }
+public sealed class IDisposableSingletonService : IIDisposableService
+{
+ public bool DisposeCalled { get; set; }
+
+ public void Dispose()
+ {
+ this.DisposeCalled = true;
}
}
diff --git a/Slim.Tests/Models/IIDisposableService.cs b/Slim.Tests/Models/IIDisposableService.cs
index 0882921..002842e 100644
--- a/Slim.Tests/Models/IIDisposableService.cs
+++ b/Slim.Tests/Models/IIDisposableService.cs
@@ -1,9 +1,8 @@
using System;
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IIDisposableService : IDisposable
{
- public interface IIDisposableService : IDisposable
- {
- bool DisposeCalled { get; set; }
- }
+ bool DisposeCalled { get; set; }
}
diff --git a/Slim.Tests/Models/IIndependentService.cs b/Slim.Tests/Models/IIndependentService.cs
index f4dccb2..954849e 100644
--- a/Slim.Tests/Models/IIndependentService.cs
+++ b/Slim.Tests/Models/IIndependentService.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IIndependentService
{
- public interface IIndependentService
- {
- }
}
diff --git a/Slim.Tests/Models/IMultiInterfaceService1.cs b/Slim.Tests/Models/IMultiInterfaceService1.cs
index 31d9848..39b2c0b 100644
--- a/Slim.Tests/Models/IMultiInterfaceService1.cs
+++ b/Slim.Tests/Models/IMultiInterfaceService1.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IMultiInterfaceService1
{
- public interface IMultiInterfaceService1
- {
- }
}
diff --git a/Slim.Tests/Models/IMultiInterfaceService2.cs b/Slim.Tests/Models/IMultiInterfaceService2.cs
index 93a542e..422f3fe 100644
--- a/Slim.Tests/Models/IMultiInterfaceService2.cs
+++ b/Slim.Tests/Models/IMultiInterfaceService2.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IMultiInterfaceService2
{
- public interface IMultiInterfaceService2
- {
- }
}
diff --git a/Slim.Tests/Models/IPrivateConstructorService.cs b/Slim.Tests/Models/IPrivateConstructorService.cs
index 91a1c56..856b2d3 100644
--- a/Slim.Tests/Models/IPrivateConstructorService.cs
+++ b/Slim.Tests/Models/IPrivateConstructorService.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IPrivateConstructorService
{
- public interface IPrivateConstructorService
- {
- }
}
diff --git a/Slim.Tests/Models/ISharedInterface.cs b/Slim.Tests/Models/ISharedInterface.cs
index 9784ec4..e1ef3bf 100644
--- a/Slim.Tests/Models/ISharedInterface.cs
+++ b/Slim.Tests/Models/ISharedInterface.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface ISharedInterface
{
- public interface ISharedInterface
- {
- }
}
diff --git a/Slim.Tests/Models/ISharedService1.cs b/Slim.Tests/Models/ISharedService1.cs
index 3f6d485..f265d76 100644
--- a/Slim.Tests/Models/ISharedService1.cs
+++ b/Slim.Tests/Models/ISharedService1.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface ISharedService1 : ISharedInterface
{
- public interface ISharedService1 : ISharedInterface
- {
- }
}
diff --git a/Slim.Tests/Models/ISharedService2.cs b/Slim.Tests/Models/ISharedService2.cs
index 1d0b08c..a7d9551 100644
--- a/Slim.Tests/Models/ISharedService2.cs
+++ b/Slim.Tests/Models/ISharedService2.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface ISharedService2 : ISharedInterface
{
- public interface ISharedService2 : ISharedInterface
- {
- }
}
diff --git a/Slim.Tests/Models/ISharedService3.cs b/Slim.Tests/Models/ISharedService3.cs
index b07896a..05f3149 100644
--- a/Slim.Tests/Models/ISharedService3.cs
+++ b/Slim.Tests/Models/ISharedService3.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface ISharedService3 : ISharedInterface
{
- public interface ISharedService3 : ISharedInterface
- {
- }
}
diff --git a/Slim.Tests/Models/IThrowingService.cs b/Slim.Tests/Models/IThrowingService.cs
index 189ad8e..e155322 100644
--- a/Slim.Tests/Models/IThrowingService.cs
+++ b/Slim.Tests/Models/IThrowingService.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public interface IThrowingService
{
- public interface IThrowingService
- {
- }
}
diff --git a/Slim.Tests/Models/IndependentService.cs b/Slim.Tests/Models/IndependentService.cs
index f90e2e6..5f9bb07 100644
--- a/Slim.Tests/Models/IndependentService.cs
+++ b/Slim.Tests/Models/IndependentService.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public class IndependentService : IIndependentService
{
- public class IndependentService : IIndependentService
- {
- }
}
diff --git a/Slim.Tests/Models/MultiConstructorService.cs b/Slim.Tests/Models/MultiConstructorService.cs
index 90eb977..9ec64e3 100644
--- a/Slim.Tests/Models/MultiConstructorService.cs
+++ b/Slim.Tests/Models/MultiConstructorService.cs
@@ -1,13 +1,19 @@
-namespace Slim.Tests.Models
-{
- public class MultiConstructorService : IIndependentService
- {
- public MultiConstructorService(int x, int y, object z)
- {
- }
+namespace Slim.Tests.Models;
- public MultiConstructorService()
- {
- }
+public class MultiConstructorService : IIndependentService
+{
+ public int X { get; }
+ public int Y { get; }
+ public object Z { get; }
+
+ public MultiConstructorService(int x, int y, object z)
+ {
+ this.X = x;
+ this.Y = y;
+ this.Z = z;
+ }
+
+ public MultiConstructorService()
+ {
}
}
diff --git a/Slim.Tests/Models/MultiInterfaceService.cs b/Slim.Tests/Models/MultiInterfaceService.cs
index c027641..a5563cd 100644
--- a/Slim.Tests/Models/MultiInterfaceService.cs
+++ b/Slim.Tests/Models/MultiInterfaceService.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public class MultiInterfaceService : IMultiInterfaceService1, IMultiInterfaceService2
{
- public class MultiInterfaceService : IMultiInterfaceService1, IMultiInterfaceService2
- {
- }
}
diff --git a/Slim.Tests/Models/NoInterfaceService.cs b/Slim.Tests/Models/NoInterfaceService.cs
index 4b5de33..06c67a7 100644
--- a/Slim.Tests/Models/NoInterfaceService.cs
+++ b/Slim.Tests/Models/NoInterfaceService.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public class NoInterfaceService
{
- public class NoInterfaceService
- {
- }
}
diff --git a/Slim.Tests/Models/PrivateConstructorService.cs b/Slim.Tests/Models/PrivateConstructorService.cs
index 4eb68b9..633e4f2 100644
--- a/Slim.Tests/Models/PrivateConstructorService.cs
+++ b/Slim.Tests/Models/PrivateConstructorService.cs
@@ -1,9 +1,8 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public sealed class PrivateConstructorService : IPrivateConstructorService
{
- public sealed class PrivateConstructorService : IPrivateConstructorService
+ private PrivateConstructorService()
{
- private PrivateConstructorService()
- {
- }
}
}
diff --git a/Slim.Tests/Models/ServiceWithPrefferedConstructor.cs b/Slim.Tests/Models/ServiceWithPrefferedConstructor.cs
index e9510e8..c258ce9 100644
--- a/Slim.Tests/Models/ServiceWithPrefferedConstructor.cs
+++ b/Slim.Tests/Models/ServiceWithPrefferedConstructor.cs
@@ -1,33 +1,38 @@
using Slim.Attributes;
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public sealed class ServiceWithPrefferedConstructor
{
- public sealed class ServiceWithPrefferedConstructor
+ public bool CalledPrefferedConstructor { get; init; }
+ public bool CalledPrefferedConstructor0 { get; init; }
+ public bool CalledPrefferedConstructor1 { get; init; }
+ public IIndependentService IndependentService { get; }
+ public IDependentService DependentService { get; }
+ public IDependentService2 DependentService2 { get; }
+
+ public ServiceWithPrefferedConstructor()
{
- public bool CalledPrefferedConstructor { get; init; }
- public bool CalledPrefferedConstructor0 { get; init; }
- public bool CalledPrefferedConstructor1 { get; init; }
+ }
- public ServiceWithPrefferedConstructor()
- {
- }
+ [PreferredConstructor]
+ public ServiceWithPrefferedConstructor(IIndependentService independentService)
+ {
+ this.CalledPrefferedConstructor = true;
+ this.IndependentService = independentService;
+ }
- [PreferredConstructor]
- public ServiceWithPrefferedConstructor(IIndependentService independentService)
- {
- this.CalledPrefferedConstructor = true;
- }
+ [PreferredConstructor(Priority = 0)]
+ public ServiceWithPrefferedConstructor(IDependentService dependentService)
+ {
+ this.CalledPrefferedConstructor0 = true;
+ this.DependentService = dependentService;
+ }
- [PreferredConstructor(Priority = 0)]
- public ServiceWithPrefferedConstructor(IDependentService dependentService)
- {
- this.CalledPrefferedConstructor0 = true;
- }
-
- [PreferredConstructor(Priority = 1)]
- public ServiceWithPrefferedConstructor(IDependentService2 dependentService2)
- {
- this.CalledPrefferedConstructor1 = true;
- }
+ [PreferredConstructor(Priority = 1)]
+ public ServiceWithPrefferedConstructor(IDependentService2 dependentService2)
+ {
+ this.CalledPrefferedConstructor1 = true;
+ this.DependentService2 = dependentService2;
}
}
diff --git a/Slim.Tests/Models/SharedService1.cs b/Slim.Tests/Models/SharedService1.cs
index d8f6587..6eab83f 100644
--- a/Slim.Tests/Models/SharedService1.cs
+++ b/Slim.Tests/Models/SharedService1.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public sealed class SharedService1 : ISharedService1
{
- public sealed class SharedService1 : ISharedService1
- {
- }
}
diff --git a/Slim.Tests/Models/SharedService2.cs b/Slim.Tests/Models/SharedService2.cs
index d33eaa5..90e2921 100644
--- a/Slim.Tests/Models/SharedService2.cs
+++ b/Slim.Tests/Models/SharedService2.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public sealed class SharedService2 : ISharedService2
{
- public sealed class SharedService2 : ISharedService2
- {
- }
}
diff --git a/Slim.Tests/Models/SharedService3.cs b/Slim.Tests/Models/SharedService3.cs
index 9f31dbe..8e9f981 100644
--- a/Slim.Tests/Models/SharedService3.cs
+++ b/Slim.Tests/Models/SharedService3.cs
@@ -1,6 +1,5 @@
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public sealed class SharedService3 : ISharedService3
{
- public sealed class SharedService3 : ISharedService3
- {
- }
}
diff --git a/Slim.Tests/Models/ThrowingService.cs b/Slim.Tests/Models/ThrowingService.cs
index 92c024f..560672b 100644
--- a/Slim.Tests/Models/ThrowingService.cs
+++ b/Slim.Tests/Models/ThrowingService.cs
@@ -1,12 +1,11 @@
using System;
-namespace Slim.Tests.Models
+namespace Slim.Tests.Models;
+
+public sealed class ThrowingService : IThrowingService
{
- public sealed class ThrowingService : IThrowingService
+ public ThrowingService()
{
- public ThrowingService()
- {
- throw new InvalidOperationException();
- }
+ throw new InvalidOperationException();
}
}
diff --git a/Slim.Tests/Resolvers/DependentServiceResolver.cs b/Slim.Tests/Resolvers/DependentServiceResolver.cs
index 3206e74..693c3c5 100644
--- a/Slim.Tests/Resolvers/DependentServiceResolver.cs
+++ b/Slim.Tests/Resolvers/DependentServiceResolver.cs
@@ -2,24 +2,23 @@
using Slim.Tests.Models;
using System;
-namespace Slim.Tests.Resolvers
+namespace Slim.Tests.Resolvers;
+
+public sealed class DependentServiceResolver : IDependencyResolver
{
- public sealed class DependentServiceResolver : IDependencyResolver
+ public bool CanResolve(Type type)
{
- public bool CanResolve(Type type)
+ if (type == typeof(IDependentService))
{
- if (type == typeof(IDependentService))
- {
- return true;
- }
-
- return false;
+ return true;
}
- public object Resolve(IServiceProvider serviceProvider, Type type)
- {
- var independentService = serviceProvider.GetService();
- return new DependentService(independentService);
- }
+ return false;
+ }
+
+ public object Resolve(IServiceProvider serviceProvider, Type type)
+ {
+ var independentService = serviceProvider.GetService();
+ return new DependentService(independentService);
}
}
diff --git a/Slim.Tests/Resolvers/IndependentServiceResolver.cs b/Slim.Tests/Resolvers/IndependentServiceResolver.cs
index c0e0f2f..4b80415 100644
--- a/Slim.Tests/Resolvers/IndependentServiceResolver.cs
+++ b/Slim.Tests/Resolvers/IndependentServiceResolver.cs
@@ -2,26 +2,25 @@
using Slim.Tests.Models;
using System;
-namespace Slim.Tests.Resolvers
+namespace Slim.Tests.Resolvers;
+
+public class IndependentServiceResolver : IDependencyResolver
{
- public class IndependentServiceResolver : IDependencyResolver
+ public int Called { get; private set; }
+
+ public bool CanResolve(Type type)
{
- public int Called { get; private set; }
-
- public bool CanResolve(Type type)
+ if (type == typeof(IIndependentService))
{
- if (type == typeof(IIndependentService))
- {
- return true;
- }
-
- return false;
+ return true;
}
- public object Resolve(IServiceProvider serviceProvider, Type type)
- {
- this.Called++;
- return new IndependentService();
- }
+ return false;
+ }
+
+ public object Resolve(IServiceProvider serviceProvider, Type type)
+ {
+ this.Called++;
+ return new IndependentService();
}
}
diff --git a/Slim.Tests/ServiceManagerTests.cs b/Slim.Tests/ServiceManagerTests.cs
index caab560..e0a6f3b 100644
--- a/Slim.Tests/ServiceManagerTests.cs
+++ b/Slim.Tests/ServiceManagerTests.cs
@@ -1,797 +1,814 @@
-using FluentAssertions;
+using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Slim.Exceptions;
using Slim.Tests.Models;
using Slim.Tests.Resolvers;
using System;
-namespace Slim.Tests
+namespace Slim.Tests;
+
+[TestClass]
+public class ServiceManagerTests
{
- [TestClass]
- public class ServiceManagerTests
+ [TestMethod]
+ public void RegisterAndRetrieveServiceUsesExistingImplementationSingleton()
{
- [TestMethod]
- public void RegisterAndRetrieveServiceUsesExistingImplementationSingleton()
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+
+ var independentService = di.GetService();
+ independentService.Should().NotBeNull();
+
+ var dependentService = di.GetService();
+ dependentService.Should().NotBeNull();
+
+ dependentService.IndependentService.Should().Be(independentService);
+ }
+
+ [TestMethod]
+ public void DependencyOnPrivateConstructorServiceThrows()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+
+ var action = new Action(() =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
- di.RegisterSingleton();
+ di.GetService();
+ });
- var independentService = di.GetService();
- independentService.Should().NotBeNull();
+ action.Should().Throw();
+ }
- var dependentService = di.GetService();
- dependentService.Should().NotBeNull();
+ [TestMethod]
+ public void DependencyOnThrowingServiceThrows()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
- dependentService.IndependentService.Should().Be(independentService);
- }
-
- [TestMethod]
- public void DependencyOnPrivateConstructorServiceThrows()
+ var action = new Action(() =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
- di.RegisterSingleton();
+ di.GetService();
+ });
- var action = new Action(() =>
- {
- di.GetService();
- });
+ action.Should().Throw();
+ }
- action.Should().Throw();
- }
+ [TestMethod]
+ public void ThrowingConstructorThrows()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
- [TestMethod]
- public void DependencyOnThrowingServiceThrows()
+ var action = new Action(() =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
- di.RegisterSingleton();
+ di.GetService();
+ });
- var action = new Action(() =>
- {
- di.GetService();
- });
+ action.Should().Throw();
+ }
- action.Should().Throw();
- }
+ [TestMethod]
+ public void RetrieveThrowsNotRegistered()
+ {
+ var di = new ServiceManager();
+ Assert.ThrowsException(() => { di.GetService(); });
+ }
- [TestMethod]
- public void ThrowingConstructorThrows()
+ [TestMethod]
+ public void RegisterAndRetrieveThrowsNoSuitableConstructorFound()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ Assert.ThrowsException(() => { di.GetService(); });
+ }
+
+ [TestMethod]
+ public void RegisterMultipleServices()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+ }
+
+ [TestMethod]
+ public void RegisterAndRetrieveService()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+
+ var dependentService = di.GetService();
+ dependentService.Should().NotBeNull();
+ }
+
+ [TestMethod]
+ public void TransientAreDifferent()
+ {
+ var di = new ServiceManager();
+ di.RegisterTransient();
+
+ var independentService = di.GetService();
+ var independentService2 = di.GetService();
+
+ independentService.Should().NotBeSameAs(independentService2);
+ }
+
+ [TestMethod]
+ public void SingletonAreTheSame()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+
+ var independentService = di.GetService();
+ var independentService2 = di.GetService();
+
+ independentService.Should().BeSameAs(independentService2);
+ }
+
+ [TestMethod]
+ public void RegisterServiceWithFactoryAndRetrieve()
+ {
+ var calledFactory = false;
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton(sp =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
+ calledFactory = true;
+ return new DependentService(sp.GetService());
+ });
- var action = new Action(() =>
- {
- di.GetService();
- });
+ var dependentService = di.GetService();
- action.Should().Throw();
- }
+ dependentService.Should().NotBeNull();
+ calledFactory.Should().BeTrue();
+ }
- [TestMethod]
- public void RetrieveThrowsNotRegistered()
+ [TestMethod]
+ public void TransientDependentAndSingletonIndependentRespectLifetime()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterTransient();
+
+ var independentService = di.GetService();
+ var dependentService = di.GetService();
+ var dependentService2 = di.GetService();
+
+ dependentService.Should().NotBeSameAs(dependentService2);
+ dependentService.IndependentService.Should().BeSameAs(dependentService2.IndependentService);
+ independentService.Should().BeSameAs(dependentService.IndependentService);
+ }
+
+ [TestMethod]
+ public void TransientDependentWithFactoryAndSingletonIndependentRespectLifetime()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterTransient(sp => new DependentService(sp.GetService()));
+
+ var independentService = di.GetService();
+ var dependentService = di.GetService();
+ var dependentService2 = di.GetService();
+
+ dependentService.Should().NotBeSameAs(dependentService2);
+ dependentService.IndependentService.Should().BeSameAs(dependentService2.IndependentService);
+ independentService.Should().BeSameAs(dependentService.IndependentService);
+ }
+
+ [TestMethod]
+ public void MultipleDeclarationsReturnSameSingleton()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+
+ var independentService = di.GetService();
+ var sameIndependentService = di.GetService();
+
+ independentService.Should().BeSameAs(sameIndependentService);
+ }
+
+ [TestMethod]
+ public void MultipleDeclarationsOfSameInterfaceThrows()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+
+ var action = new Action(() =>
{
- var di = new ServiceManager();
- Assert.ThrowsException(() => { di.GetService(); });
- }
-
- [TestMethod]
- public void RegisterAndRetrieveThrowsNoSuitableConstructorFound()
- {
- var di = new ServiceManager();
- di.RegisterSingleton();
- Assert.ThrowsException(() => { di.GetService(); });
- }
-
- [TestMethod]
- public void RegisterMultipleServices()
- {
- var di = new ServiceManager();
di.RegisterSingleton();
- di.RegisterSingleton();
- }
+ });
- [TestMethod]
- public void RegisterAndRetrieveService()
+ action.Should().Throw();
+ }
+
+ [TestMethod]
+ public void MultiInterfaceDeclarationReturnsSameSingleton()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton(registerAllInterfaces: true);
+
+ var singleton1 = di.GetService();
+ var singleton2 = di.GetService();
+
+ singleton1.Should().Be(singleton2);
+ }
+
+ [TestMethod]
+ public void MultiInterfaceDeclarationReturnsDifferentTransient()
+ {
+ var di = new ServiceManager();
+ di.RegisterTransient(registerAllInterfaces: true);
+
+ var transient1 = di.GetService();
+ var transient2 = di.GetService();
+
+ transient1.Should().NotBe(transient2);
+ }
+
+ [TestMethod]
+ public void MultiInterfaceDeclarationWithFactoryReturnsSameSingleton()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton(sp => new MultiInterfaceService(), registerAllInterfaces: true);
+
+ var singleton1 = di.GetService();
+ var singleton2 = di.GetService();
+
+ singleton1.Should().Be(singleton2);
+ }
+
+ [TestMethod]
+ public void MultiInterfaceDeclarationWithFactoryReturnsDifferentTransient()
+ {
+ var di = new ServiceManager();
+ di.RegisterTransient(sp => new MultiInterfaceService(), registerAllInterfaces: true);
+
+ var transient1 = di.GetService();
+ var transient2 = di.GetService();
+
+ transient1.Should().NotBe(transient2);
+ }
+
+ [TestMethod]
+ public void RegisterServiceManagerSingletonRegistersCurrentServiceManager()
+ {
+ var di = new ServiceManager();
+ di.RegisterServiceManager();
+ di.RegisterSingleton();
+
+ var dependentService = di.GetService();
+
+ dependentService.ServiceManager.Should().Be(di);
+ dependentService.ServiceProducer.Should().Be(di);
+ dependentService.ServiceProvider.Should().Be(di);
+ }
+
+ [TestMethod]
+ public void CatchSpecificException()
+ {
+ var di = new ServiceManager();
+ var thrown = false;
+ di.HandleException((sp, e) =>
+ {
+ thrown = true;
+ return true;
+ });
+
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+
+ thrown.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void CatchSpecificExceptionAndRethrow()
+ {
+ var di = new ServiceManager();
+ var thrown = false;
+ di.HandleException((sp, e) =>
+ {
+ thrown = true;
+ return false;
+ });
+
+ di.RegisterSingleton();
+ var action = new Action(() =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
di.RegisterSingleton();
+ });
- var dependentService = di.GetService();
- dependentService.Should().NotBeNull();
- }
+ action.Should().Throw();
+ thrown.Should().BeTrue();
+ }
- [TestMethod]
- public void TransientAreDifferent()
+ [TestMethod]
+ public void ClearAndGetShouldThrow()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+
+ var action = new Action(() =>
{
- var di = new ServiceManager();
- di.RegisterTransient();
+ di.GetService();
+ });
+ di.Clear();
- var independentService = di.GetService();
- var independentService2 = di.GetService();
+ action.Should().Throw();
+ }
- independentService.Should().NotBeSameAs(independentService2);
- }
+ [TestMethod]
+ public void ClearShouldCallDispose()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ var disposableService = (IDisposableService)di.GetService();
- [TestMethod]
- public void SingletonAreTheSame()
+ di.Clear();
+
+ disposableService.DisposeCalled.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void BuildAllSingletons()
+ {
+ var shouldCallConstructor = false;
+ var shouldNotCallConstructor = false;
+ var di = new ServiceManager();
+ di.RegisterSingleton(sp =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
-
- var independentService = di.GetService();
- var independentService2 = di.GetService();
-
- independentService.Should().BeSameAs(independentService2);
- }
-
- [TestMethod]
- public void RegisterServiceWithFactoryAndRetrieve()
+ shouldCallConstructor = true;
+ return new IndependentService();
+ });
+ di.RegisterTransient(sp =>
{
- var calledFactory = false;
- var di = new ServiceManager();
- di.RegisterSingleton();
- di.RegisterSingleton(sp =>
- {
- calledFactory = true;
- return new DependentService(sp.GetService());
- });
+ shouldNotCallConstructor = true;
+ return new DependentService(sp.GetService());
+ });
- var dependentService = di.GetService();
+ di.BuildSingletons();
- dependentService.Should().NotBeNull();
- calledFactory.Should().BeTrue();
- }
+ shouldCallConstructor.Should().BeTrue();
+ shouldNotCallConstructor.Should().BeFalse();
+ }
- [TestMethod]
- public void TransientDependentAndSingletonIndependentRespectLifetime()
+ [TestMethod]
+ public void MultipleConstructorsShouldFindUsableOne()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+
+ var service = di.GetService();
+ service.Should().NotBeNull();
+ service.Should().BeOfType();
+ }
+
+ [TestMethod]
+ public void NoInterfaceServiceShouldReturnService()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+
+ var service = di.GetService();
+ service.Should().NotBeNull();
+ service.Should().BeOfType();
+ }
+
+ [TestMethod]
+ public void UseResolverToResolveService()
+ {
+ var di = new ServiceManager();
+ var resolver = new IndependentServiceResolver();
+ di.RegisterResolver(resolver);
+ di.RegisterTransient();
+
+ var service = di.GetService();
+ service.Should().NotBeNull();
+ service.Should().BeOfType();
+ resolver.Called.Should().Be(1);
+ }
+
+ [TestMethod]
+ public void UseResolverWithoutRegisteringServiceCallsResolver()
+ {
+ var di = new ServiceManager();
+ var resolver = new IndependentServiceResolver();
+ di.RegisterResolver(resolver);
+
+ var service = di.GetService();
+ service.Should().NotBeNull();
+ service.Should().BeOfType();
+ }
+
+ [TestMethod]
+ public void UseResolverCalledOnceForSingleton()
+ {
+ var di = new ServiceManager();
+ var resolver = new IndependentServiceResolver();
+ di.RegisterResolver(resolver);
+ di.RegisterSingleton();
+
+ var service = di.GetService();
+ service.Should().NotBeNull();
+ service.Should().BeOfType();
+ resolver.Called.Should().Be(1);
+
+ var service2 = di.GetService();
+ service2.Should().NotBeNull();
+ service2.Should().BeOfType();
+ resolver.Called.Should().Be(1);
+
+ service.Should().Be(service2);
+ }
+
+ [TestMethod]
+ public void UseResolverCalledMultipleForTransient()
+ {
+ var di = new ServiceManager();
+ var resolver = new IndependentServiceResolver();
+ di.RegisterResolver(resolver);
+ di.RegisterTransient();
+
+ var service = di.GetService();
+ service.Should().NotBeNull();
+ service.Should().BeOfType();
+ resolver.Called.Should().Be(1);
+
+ var service2 = di.GetService();
+ service2.Should().NotBeNull();
+ service2.Should().BeOfType();
+ resolver.Called.Should().Be(2);
+ }
+
+ [TestMethod]
+ public void UseResolverForUndeclaredService()
+ {
+ var di = new ServiceManager();
+ var resolver = new IndependentServiceResolver();
+ di.RegisterResolver(resolver);
+ di.RegisterTransient();
+
+ var service = di.GetService();
+ service.Should().NotBeNull();
+ resolver.Called.Should().Be(1);
+ }
+
+ [TestMethod]
+ public void UseResolverUsesSecondResolver()
+ {
+ var di = new ServiceManager();
+ di.RegisterResolver(new IndependentServiceResolver());
+ di.RegisterResolver(new DependentServiceResolver());
+ di.RegisterTransient();
+ di.RegisterTransient();
+
+ var service = di.GetService();
+ service.Should().NotBeNull();
+ service.Should().BeOfType();
+
+ var service2 = di.GetService();
+ service2.Should().NotBeNull();
+ service2.Should().BeOfType();
+ }
+
+ [TestMethod]
+ public void CreateScopeCreatesNewServiceProvider()
+ {
+ var di = new ServiceManager();
+ var scopedDi = di.CreateScope();
+ scopedDi.Should().NotBeNull();
+ scopedDi.Should().NotBe(di);
+ }
+
+ [TestMethod]
+ public void ScopedServicesShouldBeNewUnderScopedProvider()
+ {
+ var di = new ServiceManager();
+ di.RegisterScoped();
+
+ var service = di.GetService();
+ var scopedDi = di.CreateScope();
+ var scopedService = scopedDi.GetService();
+
+ service.Should().NotBe(scopedService);
+ }
+
+ [TestMethod]
+ public void SingletonServicesShouldBeSameUnderScopedProvider()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ var scopedDi = di.CreateScope();
+
+ var service = di.GetService();
+ var scopedService = scopedDi.GetService();
+
+ service.Should().Be(scopedService);
+ }
+
+ [TestMethod]
+ public void LifetimesShouldBeRespected()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterScoped();
+ di.BuildSingletons();
+ var scopedDi = di.CreateScope();
+
+ var independentService1 = di.GetService();
+ var dependentService1 = di.GetService();
+ var independentService2 = scopedDi.GetService();
+ var dependentService2 = scopedDi.GetService();
+
+ independentService1.Should().Be(independentService2);
+ dependentService1.Should().NotBe(dependentService2);
+ independentService1.Should().NotBeNull();
+ independentService2.Should().NotBeNull();
+ dependentService1.Should().NotBeNull();
+ dependentService2.Should().NotBeNull();
+ }
+
+ [TestMethod]
+ public void ScopedManagerShouldHaveItsOwnLists()
+ {
+ var di = new ServiceManager() { AllowScopedManagerModifications = true };
+ di.RegisterSingleton();
+ var scopedDi = di.CreateScope();
+
+ di.RegisterSingleton();
+ scopedDi.As().RegisterSingleton();
+
+ var dependentService1 = di.GetService();
+ var dependentService2 = scopedDi.GetService();
+
+ dependentService1.Should().NotBe(dependentService2);
+ }
+
+ [TestMethod]
+ public void ScopedManagerCallsOriginalFactoryOnlyOnce()
+ {
+ var di = new ServiceManager();
+ var called = 0;
+ di.RegisterSingleton(sp =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
- di.RegisterTransient();
+ called++;
+ return new IndependentService();
+ });
+ var scopedDi = di.CreateScope();
- var independentService = di.GetService();
- var dependentService = di.GetService();
- var dependentService2 = di.GetService();
+ scopedDi.GetService();
+ called.Should().Be(1);
+ scopedDi.GetService();
+ called.Should().Be(1);
+ di.GetService();
+ called.Should().Be(1);
+ }
- dependentService.Should().NotBeSameAs(dependentService2);
- dependentService.IndependentService.Should().BeSameAs(dependentService2.IndependentService);
- independentService.Should().BeSameAs(dependentService.IndependentService);
- }
+ [TestMethod]
+ public void GetServicesReturnsAllServicesWithInterface()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
- [TestMethod]
- public void TransientDependentWithFactoryAndSingletonIndependentRespectLifetime()
+ di.GetServicesOfType().Should().HaveCount(3);
+ di.GetServicesOfType(typeof(ISharedInterface)).Should().HaveCount(3).And.AllBeAssignableTo();
+ }
+
+ [TestMethod]
+ public void DisposingServiceManagerShouldDisposeInstances()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+
+ var disposableService = di.GetService();
+ di.Dispose();
+
+ disposableService.DisposeCalled.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void DisposingServiceManagerShouldDisposeAllServices()
+ {
+ var di = new ServiceManager();
+ di.RegisterScoped();
+ di.RegisterSingleton();
+
+ var disposableService = di.GetService();
+ var disposableSingletonService = di.GetService();
+ di.Dispose();
+
+ disposableSingletonService.DisposeCalled.Should().BeTrue();
+ disposableService.DisposeCalled.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void DisposingScopedServiceManagerShouldDisposeOnlyScopedServices()
+ {
+ var di = new ServiceManager();
+ di.RegisterScoped();
+ di.RegisterSingleton();
+
+ var disposableSingletonService = di.GetService();
+ var scopedDi = di.CreateScope();
+ var disposableService = scopedDi.GetService();
+ scopedDi.Dispose();
+
+ disposableSingletonService.DisposeCalled.Should().BeFalse();
+ disposableService.DisposeCalled.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void RegisterAllInterfacesFalseShouldRegisterOnlyTypeOfObject()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+
+ di.GetService().Should().NotBeNull();
+ var action = new Action(() =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
- di.RegisterTransient(sp => new DependentService(sp.GetService()));
-
- var independentService = di.GetService();
- var dependentService = di.GetService();
- var dependentService2 = di.GetService();
-
- dependentService.Should().NotBeSameAs(dependentService2);
- dependentService.IndependentService.Should().BeSameAs(dependentService2.IndependentService);
- independentService.Should().BeSameAs(dependentService.IndependentService);
- }
-
- [TestMethod]
- public void MultipleDeclarationsReturnSameSingleton()
+ di.GetService();
+ });
+ var action2 = new Action(() =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
- di.RegisterSingleton();
+ di.GetService();
+ });
- var independentService = di.GetService();
- var sameIndependentService = di.GetService();
+ action.Should().Throw();
+ action2.Should().Throw();
+ }
- independentService.Should().BeSameAs(sameIndependentService);
- }
+ [TestMethod]
+ public void IsRegisteredReturnsTrueForRegisteredService()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton(typeof(IDependentService), typeof(DependentService));
- [TestMethod]
- public void MultipleDeclarationsOfSameInterfaceThrows()
+ var isRegistered1 = di.IsRegistered();
+ var isRegistered2 = di.IsRegistered(typeof(IDependentService));
+
+ isRegistered1.Should().BeTrue();
+ isRegistered2.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void IsRegisteredReturnsFalseForNonRegisteredService()
+ {
+ var di = new ServiceManager();
+
+ var isRegistered1 = di.IsRegistered();
+ var isRegistered2 = di.IsRegistered(typeof(IDependentService));
+
+ isRegistered1.Should().BeFalse();
+ isRegistered2.Should().BeFalse();
+ }
+
+ [TestMethod]
+ public void IsRegisteredReturnsTrueForDependencyResolver()
+ {
+ var di = new ServiceManager();
+ di.RegisterResolver(new DependentServiceResolver());
+
+ var isRegistered = di.IsRegistered();
+
+ isRegistered.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void ScopedServiceManagerWithDisallowedModificationsIsReadOnly()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ var scopedDi1 = di.CreateScope() as ServiceManager;
+
+ scopedDi1.IsReadOnly.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void ScopedServiceManagerWithAllowedModificationsIsNotReadOnly()
+ {
+ var di = new ServiceManager() { AllowScopedManagerModifications = true };
+ di.RegisterSingleton();
+ var scopedDi1 = di.CreateScope() as ServiceManager;
+
+ scopedDi1.IsReadOnly.Should().BeFalse();
+ }
+
+ [TestMethod]
+ public void ModifyingScopedManagerThrowsInvalidOperationException()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ var scopedDi1 = di.CreateScope() as ServiceManager;
+
+ var action = new Action(() => scopedDi1.RegisterSingleton());
+
+ action.Should().Throw();
+ }
+
+ [TestMethod]
+ public void ModifyingScopedManagerStillResolvesSingleton()
+ {
+ var di = new ServiceManager() { AllowScopedManagerModifications = true };
+ di.RegisterSingleton();
+ var scopedDi1 = di.CreateScope() as ServiceManager;
+ var scopedDi2 = di.CreateScope() as ServiceManager;
+ scopedDi1.RegisterSingleton();
+
+ var dependentService1 = scopedDi1.GetService();
+ var dependentService2 = scopedDi2.GetService();
+
+ dependentService1.Should().Be(dependentService2);
+ dependentService1.IndependentService.Should().Be(dependentService2.IndependentService);
+ }
+
+ [TestMethod]
+ public void ServiceWithPrefferedConstructorCallsPrefferedConstructor()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+
+ var service = di.GetService();
+
+ service.CalledPrefferedConstructor.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void ServiceWithPrefferedConstructorFallsBackToOtherConstructors()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+
+ var service = di.GetService();
+
+ service.CalledPrefferedConstructor.Should().BeFalse();
+ }
+
+ [TestMethod]
+ public void ServiceWithPrefferedConstructorCallsPrefferedConstructorWithHighestPriority()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+
+ var service = di.GetService();
+
+ service.CalledPrefferedConstructor0.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void ServiceWithPrefferedConstructorCallsPrefferedConstructorWithSecondHighestPriority()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+ di.RegisterSingleton();
+
+ var service = di.GetService();
+
+ service.CalledPrefferedConstructor1.Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void ServiceWithDoNotInjectAttribute_FailsToInject()
+ {
+ var di = new ServiceManager();
+ di.RegisterSingleton();
+
+ var action = () =>
{
- var di = new ServiceManager();
- di.RegisterSingleton();
-
- var action = new Action(() =>
- {
- di.RegisterSingleton();
- });
-
- action.Should().Throw();
- }
-
- [TestMethod]
- public void MultiInterfaceDeclarationReturnsSameSingleton()
- {
- var di = new ServiceManager();
- di.RegisterSingleton(registerAllInterfaces: true);
-
- var singleton1 = di.GetService();
- var singleton2 = di.GetService();
-
- singleton1.Should().Be(singleton2);
- }
-
- [TestMethod]
- public void MultiInterfaceDeclarationReturnsDifferentTransient()
- {
- var di = new ServiceManager();
- di.RegisterTransient(registerAllInterfaces: true);
-
- var transient1 = di.GetService();
- var transient2 = di.GetService();
-
- transient1.Should().NotBe(transient2);
- }
-
- [TestMethod]
- public void MultiInterfaceDeclarationWithFactoryReturnsSameSingleton()
- {
- var di = new ServiceManager();
- di.RegisterSingleton(sp => new MultiInterfaceService(), registerAllInterfaces: true);
-
- var singleton1 = di.GetService();
- var singleton2 = di.GetService();
-
- singleton1.Should().Be(singleton2);
- }
-
- [TestMethod]
- public void MultiInterfaceDeclarationWithFactoryReturnsDifferentTransient()
- {
- var di = new ServiceManager();
- di.RegisterTransient(sp => new MultiInterfaceService(), registerAllInterfaces: true);
-
- var transient1 = di.GetService