/// <summary> /// Use <see cref="All" /> to find a <c>Type</c> which is assignable to <paramref name="type" /> /// </summary> /// <param name="type"></param> /// <param name="typesWaitingToBeBuilt"></param> /// <param name="searchAnchor"></param> /// <returns>The <c>Type</c> if one is found, <c>null</c> if not.</returns> public Type FindTypeAssignableTo(Type type, IEnumerable <Type> typesWaitingToBeBuilt = null, object searchAnchor = null) { return(TypeFinder.FindConcreteTypeAssignableTo(type, All, typesWaitingToBeBuilt, searchAnchor)); }
/// <summary> /// Creates an instance of something assignable to <paramref name="type" /> using <see cref="Rules" /> /// and <see cref="SearchAnchor" /> /// </summary> /// <param name="type">The type of which a concrete instance is wanted.</param> /// <param name="typesWaitingToBeBuilt"> /// The 'stack' of types we are trying to build grows as instantiating a type /// recursively requires the instantion of its constructor dependencies. /// This parameter is for the benefit of recursive rules whose strategy may vary depending on what we're trying /// to build. /// </param> /// <returns>An instance of type <paramref name="type" /> if possible, <c>default(T)</c> if unable to construct one.</returns> object New(Type type, IEnumerable <Type> typesWaitingToBeBuilt) { if (typesWaitingToBeBuilt?.Count() >= RecursionLimit) { return(RecursionLimitReturnFunc(type, typesWaitingToBeBuilt, SearchAnchor)); } typesWaitingToBeBuilt = (typesWaitingToBeBuilt ?? new List <Type>()).Union(type); var instanceResult = new ActivateInstances(Instances).CreateInstance(type, typesWaitingToBeBuilt, SearchAnchor); var customRuleResult = instanceResult ?? Rules.OfType <IActivateInstanceRule>() .Select(r => r.CreateInstance(type, typesWaitingToBeBuilt, SearchAnchor)) .FirstOrDefault(); var ainfo = new ActivationInfo { TypeStack = typesWaitingToBeBuilt }; try { if (customRuleResult != null) { LastActivationTree.Add(ainfo = ActivationInfo.InstanceRule(typesWaitingToBeBuilt)); return(customRuleResult); } else if (type.IsAbstract || type.IsInterface) { ainfo = new ActivationInfo { How = "type.IsAbstract || type.IsInterface", TypeStack = typesWaitingToBeBuilt }; var concreteTypeFound = TypeFinder.FindConcreteTypeAssignableTo(type, Rules, typesWaitingToBeBuilt, SearchAnchor); return(concreteTypeFound == null ? null : New(concreteTypeFound, typesWaitingToBeBuilt)); } else if (type == typeof(string)) { LastActivationTree.Add(ainfo = ActivationInfo.ValueType(typesWaitingToBeBuilt)); return("for" + typesWaitingToBeBuilt.Reverse().Skip(1).FirstOrDefault()); } else if (type.IsValueType) { LastActivationTree.Add(ainfo = ActivationInfo.ValueType(typesWaitingToBeBuilt)); return(Activator.CreateInstance(type)); } else { ainfo = new ActivationInfo { How = "InstanceFromConstructorRules", TypeStack = typesWaitingToBeBuilt }; } return(InstanceFromConstructorRules(type, Rules, typesWaitingToBeBuilt, SearchAnchor)); } catch (Exception e) { LastErrorList?.Add(new KeyValuePair <ActivationInfo, Exception>(ainfo, e)); return(null); } }