@@ -16,54 +16,88 @@ public class SimpleContainer : IContainer
1616 #endregion
1717 #region Private methods
1818
19- private object GetInstance ( RegisteredObject registeredObject )
19+ private object GetInstance ( RegisteredObject registeredObject , HashSet < Type > resolvingTypes = null )
2020 {
2121 if ( registeredObject . Instance == null ||
2222 registeredObject . LifeCycle == LifeCycle . Transient )
2323 {
24- var constructorInfo = ResolveConstructor ( registeredObject ) ;
25- var parameters = ResolveConstructorParameters ( constructorInfo ) ;
26- registeredObject . CreateInstance ( parameters . ToArray ( ) ) ;
24+ foreach ( var constructorInfo in ResolveConstructors ( registeredObject ) )
25+ {
26+ try
27+ {
28+ if ( resolvingTypes == null )
29+ {
30+ resolvingTypes = new HashSet < Type > { registeredObject . TypeToResolve } ;
31+ }
32+ else
33+ {
34+ resolvingTypes . Add ( registeredObject . TypeToResolve ) ;
35+ }
36+
37+ var parameters = constructorInfo . GetParameters ( ) . Select ( pi => pi . ParameterType ) . ToArray ( ) ;
38+ if ( parameters . Any ( resolvingTypes . Contains ) )
39+ {
40+ throw new CyclicDependencyException ( ) ;
41+ }
42+
43+ registeredObject . CreateInstance ( parameters . Select ( pi => ResolveObject ( pi , resolvingTypes ) ) . ToArray ( ) ) ;
44+ }
45+ catch ( MissingMethodException )
46+ {
47+ continue ;
48+ }
49+ break ;
50+ }
51+ if ( registeredObject . Instance == null )
52+ {
53+ throw new MissingMethodException ( ) ;
54+ }
55+ }
56+ if ( resolvingTypes != null )
57+ {
58+ resolvingTypes . Remove ( registeredObject . TypeToResolve ) ;
2759 }
2860 return registeredObject . Instance ;
2961 }
3062
31- private ConstructorInfo ResolveConstructor ( RegisteredObject registeredObject )
63+ private IEnumerable < ConstructorInfo > ResolveConstructors ( RegisteredObject registeredObject )
3264 {
33- var constructors = registeredObject . GetType ( ) . GetConstructors ( ) ;
65+ var constructors = registeredObject . ConcreteType . GetConstructors ( ) ;
3466 //with DependencyConstructor attribute
3567 var dependencyConstructor =
3668 constructors . FirstOrDefault (
3769 ci => ci . GetCustomAttribute < DependencyConstructorAttribute > ( ) != null ) ;
3870 if ( dependencyConstructor != null )
3971 {
40- return dependencyConstructor ;
41- }
42-
43- var defaultContructor = constructors . OrderBy ( ci => ci . GetParameters ( ) . Count ( ) ) . FirstOrDefault ( ) ;
44- if ( defaultContructor == null )
72+ yield return dependencyConstructor ;
73+ }
74+ var defaultConstructors = constructors . OrderBy ( ci => ci . GetParameters ( ) . Count ( ) ) ;
75+ if ( ! defaultConstructors . Any ( ) )
4576 {
4677 throw new MissingMethodException ( ) ;
4778 }
48- return defaultContructor ;
79+ foreach ( var constructorInfo in defaultConstructors )
80+ {
81+ yield return constructorInfo ;
82+ }
4983 }
5084
51- private IEnumerable < object > ResolveConstructorParameters ( ConstructorInfo constructorInfo )
52- {
53- return constructorInfo . GetParameters ( )
54- . Select ( parameter => ResolveObject ( parameter . ParameterType ) ) ;
55- }
5685
57- private object ResolveObject ( Type typeToResolve )
86+ private object ResolveObject ( Type typeToResolve , HashSet < Type > resolvingTypes = null )
5887 {
59- RegisteredObject registeredObject = null ;
88+ RegisteredObject registeredObject ;
6089
6190 if ( ! _registeredObjects . TryGetValue ( typeToResolve , out registeredObject ) )
6291 {
63- throw new TypeNotRegisteredException ( string . Format (
64- "The type {0} has not been registered." , typeToResolve . Name ) ) ;
92+ if ( typeToResolve . IsInterface || typeToResolve . IsAbstract )
93+ {
94+ throw new TypeNotRegisteredException ( string . Format (
95+ "The type {0} has not been registered." , typeToResolve . Name ) ) ;
96+ }
97+
98+ registeredObject = new RegisteredObject ( typeToResolve , typeToResolve , LifeCycle . Transient ) ;
6599 }
66- return GetInstance ( registeredObject ) ;
100+ return GetInstance ( registeredObject , resolvingTypes ) ;
67101 }
68102
69103 #endregion
@@ -79,10 +113,10 @@ public void RegisterType<TFrom, TTo>(bool singleton = true) where TTo : TFrom
79113 _registeredObjects [ typeof ( TFrom ) ] = new RegisteredObject ( typeof ( TFrom ) , typeof ( TTo ) ,
80114 singleton
81115 ? LifeCycle . Singleton
82- : LifeCycle . Transient ) ;
116+ : LifeCycle . Transient ) ;
83117 }
84118
85- public T Resolve < T > ( )
119+ public T Resolve < T > ( )
86120 {
87121 return ( T ) ResolveObject ( typeof ( T ) ) ;
88122 }
0 commit comments