@ -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 ;
}
}