예제 #1
0
        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())));
                }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
 public IEnumerable <Type> GetDependencyContracts(Type contract)
 {
     foreach (var injectMember in TypeAnalyzer.GetInfo(contract).AllInjectables)
     {
         yield return(injectMember.ContractType);
     }
 }
예제 #4
0
        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);
        }
예제 #5
0
 public static void Inject(DiContainer container, object injectable, IEnumerable <object> additional, bool shouldUseAll)
 {
     Inject(container, injectable, additional, shouldUseAll, TypeAnalyzer.GetInfo(injectable.GetType()));
 }