diff --git a/LightweightIocContainer.Validation/LightweightIocContainer.Validation.xml b/LightweightIocContainer.Validation/LightweightIocContainer.Validation.xml
index 5bedfa5..778835c 100644
--- a/LightweightIocContainer.Validation/LightweightIocContainer.Validation.xml
+++ b/LightweightIocContainer.Validation/LightweightIocContainer.Validation.xml
@@ -13,7 +13,6 @@
Validator for your to check if everything can be resolved with your current setup
- The
diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs
index 404b561..a3fa7de 100644
--- a/LightweightIocContainer/IocContainer.cs
+++ b/LightweightIocContainer/IocContainer.cs
@@ -2,6 +2,7 @@
// Created: 2019-05-20
// Copyright(c) 2019 SimonG. All Rights Reserved.
+using System.Collections.Concurrent;
using System.Reflection;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces;
@@ -21,8 +22,8 @@ public class IocContainer : IIocContainer, IIocResolver
{
private readonly RegistrationFactory _registrationFactory;
- private readonly List<(Type type, object? instance)> _singletons = [];
- private readonly List<(Type type, Type scope, Dictionary
/// The
/// A singleton instance if existing for the given , null if not
- private object? TryGetSingletonInstance(IRegistration registration) =>
- _singletons.FirstOrDefault(s => s.type == GetType(registration)).instance; //if a singleton instance exists return it
+ private object? TryGetSingletonInstance(IRegistration registration)
+ {
+ _singletons.TryGetValue(GetType(registration), out object? value); //if a singleton instance exists return it
+ return value;
+ }
///
/// Try to get an existing multiton instance for a given
@@ -447,11 +451,11 @@ public class IocContainer : IIocContainer, IIocResolver
object scopeArgument = TryGetMultitonScopeArgument(registration, arguments);
//if a multiton for the given scope exists return it
- var matchingMultitons = _multitons.FirstOrDefault(m => m.type == registration.ImplementationType && m.scope == registration.Scope); //get instances for the given type and scope (use implementation type to resolve the correct instance for multiple multiton registrations as well)
- if (matchingMultitons == default)
+ bool foundMatchingMultitons = _multitons.TryGetValue((registration.ImplementationType, registration.Scope), out var matchingMultitons); //get instances for the given type and scope (use implementation type to resolve the correct instance for multiple multiton registrations as well)
+ if (!foundMatchingMultitons || matchingMultitons is null)
return null;
- return matchingMultitons.instances.TryGetValue(scopeArgument, out object? instance) && instance != null ? instance : null;
+ return matchingMultitons.TryGetValue(scopeArgument, out object? instance) && instance != null ? instance : null;
}
///
@@ -487,17 +491,21 @@ public class IocContainer : IIocContainer, IIocResolver
object scopeArgument = TryGetMultitonScopeArgument(registration, arguments);
//if a multiton for the given scope exists return it
- var matchingMultitons = _multitons.FirstOrDefault(m => m.type == registration.ImplementationType && m.scope == registration.Scope); //get instances for the given type and scope (use implementation type to resolve the correct instance for multiple multiton registrations as well)
- if (matchingMultitons != default)
+ bool foundMatchingMultitons = _multitons.TryGetValue((registration.ImplementationType, registration.Scope), out var matchingMultitons);
+ if (foundMatchingMultitons && matchingMultitons is not null)
{
T createdInstance = Creator.CreateInstance(registration.ImplementationType, arguments[1..]);
- matchingMultitons.instances.Add(scopeArgument, createdInstance);
+ matchingMultitons.TryAdd(scopeArgument, createdInstance);
return createdInstance;
}
T newInstance = Creator.CreateInstance(registration.ImplementationType, arguments[1..]);
- _multitons.Add((registration.ImplementationType, registration.Scope, new Dictionary { { scopeArgument, newInstance } }));
+
+ ConcurrentDictionary concurrentDictionary = new();
+ concurrentDictionary.TryAdd(scopeArgument, newInstance);
+
+ _multitons.TryAdd((registration.ImplementationType, registration.Scope), concurrentDictionary);
return newInstance;
}
@@ -758,14 +766,8 @@ public class IocContainer : IIocContainer, IIocResolver
IRegistration? registration = FindRegistration();
if (registration is not IMultitonRegistration multitonRegistration)
return;
-
- var multitonInstance = _multitons.FirstOrDefault(m => m.type == multitonRegistration.ImplementationType);
-
- //it is allowed to clear a non existing multiton instance (don't throw an exception)
- if (multitonInstance == default)
- return;
-
- _multitons.Remove(multitonInstance);
+
+ _multitons.Remove((multitonRegistration.ImplementationType, multitonRegistration.Scope), out _);
}
///
@@ -794,13 +796,13 @@ public class IocContainer : IIocContainer, IIocResolver
///
public void Dispose()
{
- _singletons.Where(s => FindRegistration(s.type) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container})
- .Select(s => s.instance)
+ _singletons.Where(s => FindRegistration(s.Key) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container})
+ .Select(s => s.Value)
.OfType()
.ForEach(d => d.Dispose());
- _multitons.Where(m => FindRegistration(m.type) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container})
- .SelectMany(m => m.instances)
+ _multitons.Where(m => FindRegistration(m.Key.type) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container})
+ .SelectMany(m => m.Value)
.Select(i => i.Value)
.OfType()
.ForEach(d => d.Dispose());
diff --git a/LightweightIocContainer/LightweightIocContainer.xml b/LightweightIocContainer/LightweightIocContainer.xml
index 32746d5..af776ea 100644
--- a/LightweightIocContainer/LightweightIocContainer.xml
+++ b/LightweightIocContainer/LightweightIocContainer.xml
@@ -1946,6 +1946,11 @@
An internal placeholder that is used to hold factory methods for types that need to be resolved during the resolve process
+
+
+ An internal placeholder that is used to hold factory methods for types that need to be resolved during the resolve process
+
+
The to be resolved
@@ -1966,6 +1971,11 @@
An internal placeholder that is used to hold types that need to be resolved during the resolving process
+
+
+ An internal placeholder that is used to hold types that need to be resolved during the resolving process
+
+
The to be resolved