コード例 #1
0
        public IEnumerator <List <object> > GetAllInstancesWithInjectSplit(InjectContext context, List <TypeValuePair> args)
        {
            Assert.IsNotNull(context);

            bool autoInject = false;

            var injectArgs = new InjectArgs()
            {
                TypeInfo           = TypeAnalyzer.GetInfo(GetTypeToCreate(context.MemberType)),
                ExtraArgs          = _extraArguments.Concat(args).ToList(),
                Context            = context,
                ConcreteIdentifier = _concreteIdentifier,
                UseAllArgs         = false,
            };

            var instance = _container.InstantiateExplicit(
                autoInject, injectArgs);

            // Return before property/field/method injection to allow circular dependencies
            yield return(new List <object>()
            {
                instance
            });

            injectArgs.UseAllArgs = true;

            _container.InjectExplicit(instance, injectArgs);
        }
コード例 #2
0
ファイル: DiContainer.cs プロジェクト: nephilagraphic/Zenject
 public IEnumerable <Type> GetDependencyContracts(Type contract)
 {
     foreach (var injectMember in TypeAnalyzer.GetInfo(contract).AllInjectables)
     {
         yield return(injectMember.ContractType);
     }
 }
コード例 #3
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.ParentType, concreteType);

                    if (TryTakingFromExtras(dependInfo.MemberType, extrasList))
                    {
                        continue;
                    }

                    var context = dependInfo.CreateInjectContext(container, null);

                    foreach (var error in ValidateContract(container, 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}"
                                     .Fmt(concreteType.Name(), String.Join(",", extrasList.Select(x => x.Name()).ToArray()), DiContainer.GetCurrentObjectGraph())));
                }
            }
        }
コード例 #4
0
        object InstantiateInternal(
            Type concreteType, IEnumerable <TypeValuePair> extraArgMapParam, InjectContext currentContext)
        {
#if !ZEN_NOT_UNITY3D
            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());
#endif

            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.".Fmt(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.MemberType, out value))
                {
                    value = Resolve(injectInfo.CreateInjectContext(this, currentContext, null));
                }

                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}'".Fmt(concreteType.Name()), e);
            }

            Inject(newObj, extraArgMap, true, typeInfo, currentContext);

            return(newObj);
        }
        IEnumerable <InjectableInfo> GetAllInjectableIncludingBaseTypes()
        {
            var info = TypeAnalyzer.GetInfo(_installerType);

            while (info != null)
            {
                foreach (var injectable in info.AllInjectables)
                {
                    yield return(injectable);
                }

                info = info.BaseTypeInfo;
            }
        }
コード例 #6
0
        void InitInstance(InjectContext context)
        {
            var concreteType = GetTypeToInstantiate(context.MemberType);

            bool autoInject = false;

            _instance = _container.InstantiateExplicit(
                concreteType, new List <TypeValuePair>(), context, Id.Identifier, autoInject);

            Assert.IsNotNull(_instance);

            // Inject after we've instantiated and set _instance so that we can support circular dependencies
            // as PostInject or field parameters
            _container.InjectExplicit(
                _instance, Enumerable.Empty <TypeValuePair>(), true,
                TypeAnalyzer.GetInfo(_instance.GetType()), context, Id.Identifier);
        }
コード例 #7
0
        public object GetInstance(InjectContext context)
        {
            if (!_hasInstance)
            {
                if (_createMethod != null)
                {
                    _instance = _createMethod(context);

                    if (_instance == null)
                    {
                        throw new ZenjectResolveException(
                                  "Unable to instantiate type '{0}' in SingletonLazyCreator".Fmt(context.MemberType));
                    }

                    _hasInstance = true;
                }
                else
                {
                    var concreteType = GetTypeToInstantiate(context.MemberType);

                    bool autoInject = false;

                    _instance = _container.InstantiateExplicit(
                        concreteType, new List <TypeValuePair>(), context, _id.Identifier, autoInject);

                    Assert.IsNotNull(_instance);

                    _hasInstance = true;

                    // Inject after we've instantiated and set the _hasInstance flag so that we can support circular dependencies
                    // as PostInject or field parameters
                    _container.InjectExplicit(
                        _instance, Enumerable.Empty <TypeValuePair>(), true,
                        TypeAnalyzer.GetInfo(_instance.GetType()), context, _id.Identifier);
                }
            }

            return(_instance);
        }
コード例 #8
0
        public IEnumerator <List <object> > GetAllInstancesWithInjectSplit(InjectContext context, List <TypeValuePair> args)
        {
            Assert.IsNotNull(context);

            object instance;

            // We still want to make sure we can get the game object during validation
            var gameObj = GetGameObject(context);

            if (!_container.IsValidating || DiContainer.CanCreateOrInjectDuringValidation(_componentType))
            {
                instance = gameObj.AddComponent(_componentType);
            }
            else
            {
                instance = new ValidationMarker(_componentType);
            }

            // Note that we don't just use InstantiateComponentOnNewGameObjectExplicit here
            // because then circular references don't work
            yield return(new List <object>()
            {
                instance
            });

            var injectArgs = new InjectArgs()
            {
                ExtraArgs          = _extraArguments.Concat(args).ToList(),
                UseAllArgs         = true,
                TypeInfo           = TypeAnalyzer.GetInfo(_componentType),
                Context            = context,
                ConcreteIdentifier = _concreteIdentifier,
            };

            _container.InjectExplicit(instance, injectArgs);

            Assert.That(injectArgs.ExtraArgs.IsEmpty());
        }
        DiContainer CreateTempContainer(List <TypeValuePair> args)
        {
            var tempSubContainer = Container.CreateSubContainer();

            var installerInjectables = TypeAnalyzer.GetInfo(_installerType);

            foreach (var argPair in args)
            {
                // We need to intelligently match on the exact parameters here to avoid the issue
                // brought up in github issue #217
                var match = installerInjectables.AllInjectables
                            .Where(x => argPair.Type.DerivesFromOrEqual(x.MemberType))
                            .OrderBy(x => ZenUtilInternal.GetInheritanceDelta(argPair.Type, x.MemberType)).FirstOrDefault();

                Assert.That(match != null,
                            "Could not find match for argument type '{0}' when injecting into sub container installer '{1}'",
                            argPair.Type, _installerType);

                tempSubContainer.Bind(match.MemberType)
                .FromInstance(argPair.Value).WhenInjectedInto(_installerType);
            }

            return(tempSubContainer);
        }
コード例 #10
0
 public static void Inject(DiContainer container, object injectable, IEnumerable <object> additional, bool shouldUseAll)
 {
     Inject(container, injectable, additional, shouldUseAll, TypeAnalyzer.GetInfo(injectable.GetType()));
 }
コード例 #11
0
 public static void Inject(this DiContainer container, object injectable, IEnumerable <object> additional, bool shouldUseAll)
 {
     container.Inject(
         injectable, additional, shouldUseAll,
         TypeAnalyzer.GetInfo(injectable.GetType()), new InjectContext(container, injectable.GetType(), null));
 }
コード例 #12
0
 public static void Inject(this DiContainer container, object injectable, IEnumerable <object> additional, InjectContext context)
 {
     container.Inject(injectable, additional, false,
                      TypeAnalyzer.GetInfo(injectable.GetType()), context);
 }
コード例 #13
0
 public static void Inject(this DiContainer container, object injectable, InjectContext context)
 {
     container.Inject(
         injectable, Enumerable.Empty <object>(), false,
         TypeAnalyzer.GetInfo(injectable.GetType()), context);
 }
コード例 #14
0
ファイル: DiContainer.cs プロジェクト: zeljkokalezic/Zenject
        object InstantiateInternal(
            Type concreteType, IEnumerable <TypeValuePair> extraArgs, InjectContext currentContext, string concreteIdentifier, bool autoInject)
        {
#if !ZEN_NOT_UNITY3D
            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 InstantiatePrefabForComponent, InstantiatePrefab, InstantiateComponentOnNewGameObject, InstantiateGameObject, or InstantiateComponent.  You may also want to use GameObjectFactory class or plain old GameObject.Instantiate.", concreteType.Name());
#endif

            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.".Fmt(concreteType));
            }

            // Make a copy since we remove from it below
            var extraArgList = extraArgs.ToList();
            var paramValues  = new List <object>();

            foreach (var injectInfo in typeInfo.ConstructorInjectables)
            {
                object value;

                if (!InstantiateUtil.PopValueWithType(extraArgList, injectInfo.MemberType, out value))
                {
                    value = Resolve(injectInfo.CreateInjectContext(this, currentContext, null, concreteIdentifier));
                }

                paramValues.Add(value);
            }

            object newObj;

            try
            {
#if PROFILING_ENABLED
                using (ProfileBlock.Start("{0}.{0}()", concreteType))
#endif
                {
                    newObj = typeInfo.InjectConstructor.Invoke(paramValues.ToArray());
                }
            }
            catch (Exception e)
            {
                throw new ZenjectResolveException(
                          "Error occurred while instantiating object with type '{0}'".Fmt(concreteType.Name()), e);
            }

            if (autoInject)
            {
                InjectExplicit(newObj, extraArgList, true, typeInfo, currentContext, concreteIdentifier);
            }
            else
            {
                if (!extraArgList.IsEmpty())
                {
                    throw new ZenjectResolveException(
                              "Passed unnecessary parameters when injecting into type '{0}'. \nExtra Parameters: {1}\nObject graph:\n{2}"
                              .Fmt(newObj.GetType().Name(), String.Join(",", extraArgList.Select(x => x.Type.Name()).ToArray()), currentContext.GetObjectGraphString()));
                }
            }

            return(newObj);
        }
コード例 #15
0
ファイル: DiContainer.cs プロジェクト: zeljkokalezic/Zenject
 public void InjectExplicit(object injectable, List <TypeValuePair> additional, InjectContext context)
 {
     InjectExplicit(
         injectable, additional, true,
         TypeAnalyzer.GetInfo(injectable.GetType()), context, null);
 }
コード例 #16
0
ファイル: DiContainer.cs プロジェクト: zeljkokalezic/Zenject
 public void Inject(
     object injectable, IEnumerable <object> additional, bool shouldUseAll, InjectContext context)
 {
     Inject(
         injectable, additional, shouldUseAll, context, TypeAnalyzer.GetInfo(injectable.GetType()));
 }