public static IEnumerable <ZenjectResolveException> ValidateObjectGraph( DiContainer container, Type concreteType, params Type[] extras) { using (container.PushLookup(concreteType)) { var typeInfo = TypeAnalyzer.GetInfo(concreteType); var extrasList = extras.ToList(); foreach (var dependInfo in typeInfo.AllInjectables) { Assert.IsEqual(dependInfo.EnclosingType, concreteType); if (TryTakingFromExtras(dependInfo.ContractType, extrasList)) { continue; } var context = new InjectContext( dependInfo, DiContainer.LookupsInProgress.ToList(), null); foreach (var error in ValidateContract( container, dependInfo.ContractType, context)) { yield return(error); } } if (!extrasList.IsEmpty()) { yield return(new ZenjectResolveException( "Found unnecessary extra parameters passed when injecting into '{0}' with types '{1}'. \nObject graph:\n{2}" .With(concreteType.Name(), String.Join(",", extrasList.Select(x => x.Name()).ToArray()), DiContainer.GetCurrentObjectGraph()))); } } }
object InstantiateInternal( Type concreteType, params object[] constructorArgs) { Assert.That(!concreteType.DerivesFrom <UnityEngine.Component>(), "Error occurred while instantiating object of type '{0}'. Instantiator should not be used to create new mono behaviours. Must use GameObjectInstantiator, GameObjectFactory, or GameObject.Instantiate.", concreteType.Name()); var typeInfo = TypeAnalyzer.GetInfo(concreteType); if (typeInfo.InjectConstructor == null) { throw new ZenjectResolveException( "More than one or zero constructors found for type '{0}' when creating dependencies. Use one [Inject] attribute to specify which to use.".With(concreteType)); } var paramValues = new List <object>(); var extrasList = new List <object>(constructorArgs); Assert.That(!extrasList.Contains(null), "Null value given to factory constructor arguments. This is currently not allowed"); foreach (var injectInfo in typeInfo.ConstructorInjectables) { var found = false; foreach (var extra in extrasList) { if (extra.GetType().DerivesFromOrEqual(injectInfo.ContractType)) { found = true; paramValues.Add(extra); extrasList.Remove(extra); break; } } if (!found) { paramValues.Add(_container.Resolve(injectInfo)); } } object newObj; try { using (ProfileBlock.Start("{0}.{0}()".With(concreteType))) { newObj = typeInfo.InjectConstructor.Invoke(paramValues.ToArray()); } } catch (Exception e) { throw new ZenjectResolveException( "Error occurred while instantiating object with type '{0}'".With(concreteType.Name()), e); } FieldsInjecter.Inject(_container, newObj, extrasList, true, typeInfo); return(newObj); }
public IEnumerable <Type> GetDependencyContracts(Type contract) { foreach (var injectMember in TypeAnalyzer.GetInfo(contract).AllInjectables) { yield return(injectMember.ContractType); } }
object InstantiateInternal( Type concreteType, IEnumerable <TypeValuePair> extraArgMapParam) { Assert.That(!concreteType.DerivesFrom <UnityEngine.Component>(), "Error occurred while instantiating object of type '{0}'. Instantiator should not be used to create new mono behaviours. Must use GameObjectInstantiator, GameObjectFactory, or GameObject.Instantiate.", concreteType.Name()); var typeInfo = TypeAnalyzer.GetInfo(concreteType); if (typeInfo.InjectConstructor == null) { throw new ZenjectResolveException( "More than one or zero constructors found for type '{0}' when creating dependencies. Use one [Inject] attribute to specify which to use.".With(concreteType)); } // Make a copy since we remove from it below var extraArgMap = extraArgMapParam.ToList(); var paramValues = new List <object>(); foreach (var injectInfo in typeInfo.ConstructorInjectables) { object value; if (!InstantiateUtil.PopValueWithType(extraArgMap, injectInfo.ContractType, out value)) { value = _container.Resolve(injectInfo); } paramValues.Add(value); } object newObj; try { using (ProfileBlock.Start("{0}.{0}()", concreteType)) { newObj = typeInfo.InjectConstructor.Invoke(paramValues.ToArray()); } } catch (Exception e) { throw new ZenjectResolveException( "Error occurred while instantiating object with type '{0}'".With(concreteType.Name()), e); } FieldsInjecter.Inject(_container, newObj, extraArgMap, true, typeInfo); return(newObj); }
public static void Inject(DiContainer container, object injectable, IEnumerable <object> additional, bool shouldUseAll) { Inject(container, injectable, additional, shouldUseAll, TypeAnalyzer.GetInfo(injectable.GetType())); }