Example #1
0
            public override object Resolve()
            {
                if (ConstructorInfo == null)
                {
                    throw new InvalidOperationException($"No constructor info for type {InterfaceType.FullName}");
                }

                // If parameterless, create instance
                if (Parameters == null)
                {
                    return(ConstructorInfo.Invoke(null));
                }

                // If parameters, recursively create parameters instance
                object[] parameters = new object[Parameters.Count];
                for (int i = 0; i < Parameters.Count; i++)
                {
                    ResolveNodeBase unspecializedParameter = Parameters[i];

                    object parameterValue = unspecializedParameter.Resolve();
                    parameters[i] = parameterValue;
                }
                // and create instance using parameters
                return(ConstructorInfo.Invoke(parameters));
            }
Example #2
0
        private ResolveNodeBase InnerBuildResolveTree(Type interfaceType, ICollection <Type> discoveredTypes, List <IParameterValue> userDefinedParameters = null)
        {
            // Factory ?
            Func <object> factory;

            if (_factories.TryGetValue(interfaceType, out factory))
            {
                return new FactoryNode
                       {
                           InterfaceType = interfaceType,
                           Factory       = factory
                       }
            }
            ;
            // Instance ?
            object instance;

            if (_instances.TryGetValue(interfaceType, out instance))
            {
                return new InstanceNode
                       {
                           InterfaceType = interfaceType,
                           Instance      = instance
                       }
            }
            ;

            // Implementation ?
            Type implementationType;

            if (!_implementations.TryGetValue(interfaceType, out implementationType))
            {
                return(ErrorNode.TypeNotRegistered);
            }

            ConstructorInfo[] constructorInfos = implementationType.GetConstructors();

            // Valid constructor ?
            if (constructorInfos.Length == 0 ||
                (constructorInfos.Length == 1 && !constructorInfos[0].IsPublic))
            {
                return(ErrorNode.NoPublicConstructorOrNoConstructor);
            }

            // Get parameters for each ctor
            var constructorAndParameters = constructorInfos.Select(x => new
            {
                Constructor = x,
                Parameters  = x.GetParameters()
            }).ToList();

            // Get first parameterless if any
            var parameterless = constructorAndParameters.FirstOrDefault(x => x.Parameters.Length == 0);

            if (parameterless != null)
            {
                return new BuildableNode
                       {
                           InterfaceType   = interfaceType,
                           ConstructorInfo = parameterless.Constructor
                       }
            }
            ;

            // Check if every ctor's parameter is registered in container or resolvable, returns first resolvable
            foreach (var c in constructorAndParameters)
            {
                List <ResolveNodeBase> parametersResolvable = new List <ResolveNodeBase>(c.Parameters.Length);

                // Try to resolved every parameters
                bool ok = true;
                foreach (ParameterInfo parameterInfo in c.Parameters)
                {
                    IParameterValue parameterValue = userDefinedParameters?.FirstOrDefault(x => x.Name == parameterInfo.Name);
                    if (parameterValue != null)
                    {
                        ValueNode parameter = new ValueNode
                        {
                            InterfaceType  = null,
                            ParameterValue = parameterValue
                        };
                        parametersResolvable.Add(parameter);
                    }
                    else
                    {
                        if (discoveredTypes.Any(x => x == parameterInfo.ParameterType)) // check cyclic dependency
                        {
                            ok = false;
                            break;
                        }

                        discoveredTypes.Add(parameterInfo.ParameterType);    // add parameter type to discovered type
                        ResolveNodeBase parameter = InnerBuildResolveTree(parameterInfo.ParameterType, discoveredTypes, userDefinedParameters);
                        discoveredTypes.Remove(parameterInfo.ParameterType); // remove parameter type from discovered type

                        if (parameter is ErrorNode)                          // once an invalid ctor parameter has been found, try next ctor
                        {
                            ok = false;
                            break;
                        }
                        parametersResolvable.Add(parameter);
                    }
                }

                if (ok)
                {
                    return new BuildableNode
                           {
                               InterfaceType   = interfaceType,
                               ConstructorInfo = c.Constructor,
                               Parameters      = parametersResolvable
                           }
                }
                ;
            }
            return(ErrorNode.NoResolvableConstructor);
        }

        #endregion
    }
}