#19: use `ConditionalWeakTable<>` for _multitons

pull/32/head
Simon Gockner 6 years ago
parent e87cd58973
commit dbb659bf39
  1. 22
      LightweightIocContainer/IocContainer.cs

@ -6,6 +6,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using JetBrains.Annotations; using JetBrains.Annotations;
using LightweightIocContainer.Exceptions; using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces; using LightweightIocContainer.Interfaces;
@ -20,8 +21,8 @@ namespace LightweightIocContainer
public class IocContainer : IIocContainer public class IocContainer : IIocContainer
{ {
private readonly List<IRegistrationBase> _registrations = new List<IRegistrationBase>(); private readonly List<IRegistrationBase> _registrations = new List<IRegistrationBase>();
private readonly List<(Type type, object instance)> _singletons = new List<(Type, object)>(); //TODO: Think about the usage of ConditionalWeakTable<> private readonly List<(Type type, object instance)> _singletons = new List<(Type, object)>();
private readonly List<(Type type, Type scope, List<(object scopeInstance, object instance)> instances)> _multitons = new List<(Type, Type, List<(object, object)>)>(); private readonly List<(Type type, Type scope, ConditionalWeakTable<object, object> instances)> _multitons = new List<(Type, Type, ConditionalWeakTable<object, object>)>();
/// <summary> /// <summary>
/// Install the given installers for the current <see cref="IocContainer"/> /// Install the given installers for the current <see cref="IocContainer"/>
@ -162,21 +163,24 @@ namespace LightweightIocContainer
throw new MultitonResolveException($"Can not resolve multiton without the first argument being the scope (should be of type {registration.Scope}).", typeof(T)); throw new MultitonResolveException($"Can not resolve multiton without the first argument being the scope (should be of type {registration.Scope}).", typeof(T));
//if a multiton for the given scope exists return it //if a multiton for the given scope exists return it
var instances = _multitons.FirstOrDefault(m => m.type == typeof(T) && m.scope == registration.Scope).instances; var instances = _multitons.FirstOrDefault(m => m.type == typeof(T) && m.scope == registration.Scope).instances; //get instances for the given type and scope
if (instances != null && instances.Any()) if (instances != null)
{ {
var instance = instances.FirstOrDefault(i => i.scopeInstance.Equals(scopeArgument)); if (instances.TryGetValue(scopeArgument, out object instance))
if (instance != (null, null)) return (T) instance;
return (T) instance.instance;
T createdInstance = CreateInstance(registration, arguments); T createdInstance = CreateInstance(registration, arguments);
instances.Add((scopeArgument, createdInstance)); instances.Add(scopeArgument, createdInstance);
return createdInstance; return createdInstance;
} }
T newInstance = CreateInstance(registration, arguments); T newInstance = CreateInstance(registration, arguments);
_multitons.Add((typeof(T), registration.Scope, new List<(object, object)> {(scopeArgument, newInstance)}));
ConditionalWeakTable<object, object> weakTable = new ConditionalWeakTable<object, object>();
weakTable.Add(scopeArgument, newInstance);
_multitons.Add((typeof(T), registration.Scope, weakTable));
return newInstance; return newInstance;
} }

Loading…
Cancel
Save