Esempio n. 1
0
        public List <object> GetAllInstancesWithInjectSplit(
            InjectContext context, List <TypeValuePair> args, out Action injectAction)
        {
            Assert.IsEmpty(args);
            Assert.IsNotNull(context);

            Assert.That(typeof(TReturn).DerivesFromOrEqual(context.MemberType));

            injectAction = null;
            if (_container.IsValidating && !TypeAnalyzer.ShouldAllowDuringValidation(context.MemberType))
            {
                return(new List <object>()
                {
                    new ValidationMarker(typeof(TReturn))
                });
            }
            else
            {
                var result = _method(context);

                if (result == null)
                {
                    throw Assert.CreateException(
                              "Method '{0}' returned null when list was expected. Object graph:\n {1}",
                              _method.ToDebugString(), context.GetObjectGraphString());
                }

                return(result.Cast <object>().ToList());
            }
        }
Esempio n. 2
0
        public IEnumerator <List <object> > GetAllInstancesWithInjectSplit(InjectContext context, List <TypeValuePair> args)
        {
            Assert.IsEmpty(args);
            Assert.IsNotNull(context);

            Assert.That(typeof(TReturn).DerivesFromOrEqual(context.MemberType));

            if (_container.IsValidating && !DiContainer.CanCreateOrInjectDuringValidation(context.MemberType))
            {
                yield return(new List <object>()
                {
                    new ValidationMarker(typeof(TReturn))
                });
            }
            else
            {
                var result = _method(context);

                if (result == null)
                {
                    throw Assert.CreateException(
                              "Method '{0}' returned null when list was expected. Object graph: {1}",
                              _method.ToDebugString(), context.GetObjectGraphString());
                }

                yield return(result.Cast <object>().ToList());
            }
        }
Esempio n. 3
0
        public List <object> GetAllInstancesWithInjectSplit(
            InjectContext context, List <TypeValuePair> args, out Action injectAction)
        {
            Assert.IsNotNull(context);

            if (_instances != null)
            {
                injectAction = null;
                return(_instances);
            }

#if !ZEN_MULTITHREADING
            // This should only happen with constructor injection
            // Field or property injection should allow circular dependencies
            if (_isCreatingInstance)
            {
                Type instanceType = _creator.GetInstanceType(context);
                throw Assert.CreateException(
                          "Found circular dependency when creating type '{0}'. Object graph:\n {1}{2}\n",
                          instanceType, context.GetObjectGraphString(), instanceType.PrettyName());
            }

            _isCreatingInstance = true;
#endif

            _instances = _creator.GetAllInstancesWithInjectSplit(context, args, out injectAction);
            Assert.IsNotNull(_instances);

#if !ZEN_MULTITHREADING
            _isCreatingInstance = false;
#endif
            return(_instances);
        }
        public IEnumerable <ZenjectResolveException> ValidateBinding(
            Type componentType, InjectContext context)
        {
            if (!ContainsComponent(componentType))
            {
                yield return(new ZenjectResolveException(
                                 "Could not find component of type '{0}' in prefab with name '{1}' \nObject graph:\n{2}"
                                 .Fmt(componentType.Name(), _id.Prefab.name, context.GetObjectGraphString())));

                yield break;
            }

            // In most cases componentType will be a MonoBehaviour but we also want to allow interfaces
            // And in that case we can't validate it
            if (!componentType.IsAbstract())
            {
                // Note that we always want to cache _container instead of using context.Container
                // since for singletons, the container they are accessed from should not determine
                // the container they are instantiated with
                // Transients can do that but not singletons
                foreach (var err in _container.ValidateObjectGraph(componentType, context))
                {
                    yield return(err);
                }
            }
        }
Esempio n. 5
0
        public void GetAllInstancesWithInjectSplit(
            InjectContext context, List <TypeValuePair> args, out Action injectAction, List <object> buffer)
        {
            Assert.IsEmpty(args);
            Assert.IsNotNull(context);

            injectAction = null;
            if (_container.IsValidating && !TypeAnalyzer.ShouldAllowDuringValidation(context.MemberType))
            {
                buffer.Add(new ValidationMarker(context.MemberType));
            }
            else
            {
                var result = _method(context);

                if (result == null)
                {
                    throw Assert.CreateException(
                              "Method '{0}' returned null when list was expected. Object graph:\n {1}",
                              _method.ToDebugString(), context.GetObjectGraphString());
                }

                foreach (var obj in result)
                {
                    buffer.Add(obj);
                }
            }
        }
Esempio n. 6
0
        public override object GetInstance(InjectContext context)
        {
            Assert.That(_returnType.DerivesFromOrEqual(context.MemberType));

            var obj = _method(context);

            Assert.That(obj != null, () =>
                "Method provider returned null when looking up type '{0}'. \nObject graph:\n{1}".Fmt(_returnType.Name(), context.GetObjectGraphString()));

            return obj;
        }
        public override IEnumerable<ZenjectResolveException> ValidateBinding(InjectContext context)
        {
            if (!_creator.ContainsComponent(_concreteType))
            {
                yield return new ZenjectResolveException(
                    "Could not find component of type '{0}' in prefab with name '{1}' \nObject graph:\n{2}"
                    .Fmt(_concreteType.Name(), _creator.Prefab.name, context.GetObjectGraphString()));
                yield break;
            }

            foreach (var err in BindingValidator.ValidateObjectGraph(_container, _concreteType, context, null))
            {
                yield return err;
            }
        }
        public override IEnumerable <ZenjectResolveException> ValidateBinding(InjectContext context)
        {
            if (!_creator.ContainsComponent(_concreteType))
            {
                yield return(new ZenjectResolveException(
                                 "Could not find component of type '{0}' in prefab with name '{1}' \nObject graph:\n{2}"
                                 .Fmt(_concreteType.Name(), _creator.Prefab.name, context.GetObjectGraphString())));

                yield break;
            }

            foreach (var err in BindingValidator.ValidateObjectGraph(_container, _concreteType, context))
            {
                yield return(err);
            }
        }
        public override object GetInstance(InjectContext context)
        {
            Assert.That(_componentType.DerivesFromOrEqual(context.MemberType));

            if (_instance == null)
            {
                Assert.That(!_container.AllowNullBindings,
                    "Tried to instantiate a MonoBehaviour with type '{0}' during validation. Object graph: {1}", _componentType, context.GetObjectGraphString());

                _instance = _gameObject.AddComponent(_componentType);
                Assert.That(_instance != null);

                _container.Inject(_instance);
            }

            return _instance;
        }
        public void GetAllInstancesWithInjectSplit(
            InjectContext context, List <TypeValuePair> args, out Action injectAction, List <object> buffer)
        {
            Assert.IsNotNull(context);

#if ZEN_MULTITHREADING
            lock (_locker)
#endif
            {
                var instances = TryGetMatchFromCache(context.MemberType);

                if (instances != null)
                {
                    injectAction = null;
                    buffer.AllocFreeAddRange(instances);
                    return;
                }

#if !ZEN_MULTITHREADING
                // This should only happen with constructor injection
                // Field or property injection should allow circular dependencies
                if (_isCreatingInstance)
                {
                    var instanceType = _creator.GetInstanceType(context);
                    throw Assert.CreateException(
                              "Found circular dependency when creating type '{0}'. Object graph:\n {1}{2}\n",
                              instanceType, context.GetObjectGraphString(), instanceType);
                }

                _isCreatingInstance = true;
#endif

                instances = new List <object>();
                _creator.GetAllInstancesWithInjectSplit(
                    context, args, out injectAction, instances);
                Assert.IsNotNull(instances);

                _cachedInstances.Add(instances);
#if !ZEN_MULTITHREADING
                _isCreatingInstance = false;
#endif
                buffer.AllocFreeAddRange(instances);
            }
        }
        public override IEnumerable <ZenjectResolveException> ValidateBinding(InjectContext context)
        {
            if (!_creator.ContainsComponent(_concreteType))
            {
                yield return(new ZenjectResolveException(
                                 "Could not find component of type '{0}' in prefab with name '{1}' \nObject graph:\n{2}"
                                 .Fmt(_concreteType.Name(), _creator.Prefab.name, context.GetObjectGraphString())));

                yield break;
            }

            // Note that we always want to cache _container instead of using context.Container
            // since for singletons, the container they are accessed from should not determine
            // the container they are instantiated with
            // Transients can do that but not singletons
            foreach (var err in _container.ValidateObjectGraph(_concreteType, context))
            {
                yield return(err);
            }
        }
        public IEnumerator <List <object> > GetAllInstancesWithInjectSplit(InjectContext context, List <TypeValuePair> args)
        {
            Assert.IsNotNull(context);

            if (_instances != null)
            {
                yield return(_instances);

                yield break;
            }

#if !ZEN_MULTITHREADING
            // This should only happen with constructor injection
            // Field or property injection should allow circular dependencies
            if (_isCreatingInstance)
            {
                throw Assert.CreateException(
                          "Found circular dependency when creating type '{0}'. Object graph: {1}",
                          _creator.GetInstanceType(context), context.GetObjectGraphString());
            }
#endif

            _isCreatingInstance = true;

            var runner = _creator.GetAllInstancesWithInjectSplit(context, args);

            // First get instance
            bool hasMore = runner.MoveNext();

            _instances = runner.Current;
            Assert.IsNotNull(_instances);
            _isCreatingInstance = false;

            yield return(_instances);

            // Now do injection
            while (hasMore)
            {
                hasMore = runner.MoveNext();
            }
        }
        public object GetInstance(InjectContext context)
        {
            Assert.That(ComponentType.DerivesFromOrEqual(context.MemberType));

            if (_instance == null)
            {
                Assert.That(!_container.IsValidating,
                    "Tried to instantiate a MonoBehaviour with type '{0}' during validation. Object graph: {1}", ComponentType, context.GetObjectGraphString());

                // Note that we always want to cache _container instead of using context.Container
                // since for singletons, the container they are accessed from should not determine
                // the container they are instantiated with
                // Transients can do that but not singletons

                _instance = GameObject.AddComponent(ComponentType);
                Assert.That(_instance != null);

                _container.Inject(_instance, new object[0], true, context);
            }

            return _instance;
        }
        public DiContainer CreateSubContainer(List <TypeValuePair> args, InjectContext context,
                                              out Action injectAction)
        {
            // We can't really support arguments if we are using the cached value since
            // the arguments might change when called after the first time
            Assert.IsEmpty(args);

#if ZEN_MULTITHREADING
            lock (_locker)
#endif
            {
                if (_subContainer == null)
                {
#if !ZEN_MULTITHREADING
                    Assert.That(!_isLookingUp,
                                "Found unresolvable circular dependency when looking up sub container!  Object graph:\n {0}",
                                context.GetObjectGraphString());
                    _isLookingUp = true;
#endif

                    _subContainer = _subCreator.CreateSubContainer(
                        new List <TypeValuePair>(), context, out injectAction);

#if !ZEN_MULTITHREADING
                    _isLookingUp = false;
#endif

                    Assert.IsNotNull(_subContainer);
                }
                else
                {
                    injectAction = null;
                }

                return(_subContainer);
            }
        }
Esempio n. 15
0
        public override IEnumerable<ZenjectResolveException> ValidateBinding(InjectContext context)
        {
            if (!_creator.ContainsComponent(_instanceType))
            {
                yield return new ZenjectResolveException(
                    "Could not find component of type '{0}' in prefab with name '{1}' \nObject graph:\n{2}"
                    .Fmt(_instanceType.Name(), _creator.Prefab.name, context.GetObjectGraphString()));
                yield break;
            }

            // In most cases _instanceType will be a MonoBehaviour but we also want to allow interfaces
            // And in that case we can't validate it
            if (!_instanceType.IsAbstract)
            {
                // Note that we always want to cache _container instead of using context.Container
                // since for singletons, the container they are accessed from should not determine
                // the container they are instantiated with
                // Transients can do that but not singletons
                foreach (var err in _container.ValidateObjectGraph(_instanceType, context))
                {
                    yield return err;
                }
            }
        }
        public override object GetInstance(InjectContext context)
        {
            Assert.That(_returnType.DerivesFromOrEqual(context.MemberType));

            var obj = _method(context);

            Assert.That(obj != null, () =>
                        "Method provider returned null when looking Up type '{0}'. \nObject graph:\n{1}".Fmt(_returnType.Name(), context.GetObjectGraphString()));

            return(obj);
        }
Esempio n. 17
0
        // Iterate over fields/properties on the given object and inject any with the [Inject] attribute
        internal void Inject(
            object injectable, IEnumerable <TypeValuePair> extraArgMapParam,
            bool shouldUseAll, ZenjectTypeInfo typeInfo, InjectContext context)
        {
            Assert.IsEqual(typeInfo.TypeAnalyzed, injectable.GetType());
            Assert.That(injectable != null);

#if !ZEN_NOT_UNITY3D
            Assert.That(injectable.GetType() != typeof(GameObject),
                        "Use InjectGameObject to Inject game objects instead of Inject method");
#endif

            // Make a copy since we remove from it below
            var extraArgMap = extraArgMapParam.ToList();

            foreach (var injectInfo in typeInfo.FieldInjectables.Concat(typeInfo.PropertyInjectables))
            {
                object value;

                if (InstantiateUtil.PopValueWithType(extraArgMap, injectInfo.MemberType, out value))
                {
                    injectInfo.Setter(injectable, value);
                }
                else
                {
                    value = Resolve(
                        injectInfo.CreateInjectContext(this, context, injectable));

                    if (injectInfo.Optional && value == null)
                    {
                        // Do not override in this case so it retains the hard-coded value
                    }
                    else
                    {
                        injectInfo.Setter(injectable, value);
                    }
                }
            }

            foreach (var method in typeInfo.PostInjectMethods)
            {
                using (ProfileBlock.Start("{0}.{1}()", injectable.GetType(), method.MethodInfo.Name))
                {
                    var paramValues = new List <object>();

                    foreach (var injectInfo in method.InjectableInfo)
                    {
                        object value;

                        if (!InstantiateUtil.PopValueWithType(extraArgMap, injectInfo.MemberType, out value))
                        {
                            value = Resolve(
                                injectInfo.CreateInjectContext(this, context, injectable));
                        }

                        paramValues.Add(value);
                    }

                    method.MethodInfo.Invoke(injectable, paramValues.ToArray());
                }
            }

            if (shouldUseAll && !extraArgMap.IsEmpty())
            {
                throw new ZenjectResolveException(
                          "Passed unnecessary parameters when injecting into type '{0}'. \nExtra Parameters: {1}\nObject graph:\n{2}"
                          .Fmt(injectable.GetType().Name(), String.Join(",", extraArgMap.Select(x => x.Type.Name()).ToArray()), context.GetObjectGraphString()));
            }
        }
Esempio n. 18
0
        public static IEnumerable <ZenjectResolveException> ValidateObjectGraph(
            DiContainer container, Type concreteType, InjectContext currentContext, string concreteIdentifier, params Type[] extras)
        {
            var typeInfo   = TypeAnalyzer.GetInfo(concreteType);
            var extrasList = extras.ToList();

            foreach (var dependInfo in typeInfo.AllInjectables)
            {
                Assert.IsEqual(dependInfo.ObjectType, concreteType);

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

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

                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()), currentContext.GetObjectGraphString())));
            }
        }
Esempio n. 19
0
        public static IEnumerable <ZenjectResolveException> ValidateContract(DiContainer container, InjectContext context)
        {
            var matches = container.GetProviderMatches(context);

            if (matches.Count == 1)
            {
                foreach (var error in matches.Single().ValidateBinding(context))
                {
                    yield return(error);
                }
            }
            else
            {
                if (ReflectionUtil.IsGenericList(context.MemberType))
                {
                    var subContext = context.ChangeMemberType(context.MemberType.GetGenericArguments().Single());

                    matches = container.GetProviderMatches(subContext);

                    if (matches.IsEmpty())
                    {
                        if (!context.Optional)
                        {
                            if (container.FallbackProvider != null)
                            {
                                foreach (var error in container.FallbackProvider.ValidateBinding(context))
                                {
                                    yield return(error);
                                }
                            }
                            else
                            {
                                yield return(new ZenjectResolveException(
                                                 "Could not find dependency with type 'List<{0}>'{1}.  If the empty list is also valid, you can allow this by using the [InjectOptional] attribute.' \nObject graph:\n{2}"
                                                 .Fmt(
                                                     subContext.MemberType.Name(),
                                                     (context.ObjectType == null ? "" : " when injecting into '{0}'".Fmt(context.ObjectType.Name())),
                                                     context.GetObjectGraphString())));
                            }
                        }
                    }
                    else
                    {
                        foreach (var match in matches)
                        {
                            foreach (var error in match.ValidateBinding(context))
                            {
                                yield return(error);
                            }
                        }
                    }
                }
                else
                {
                    if (!context.Optional)
                    {
                        if (matches.IsEmpty())
                        {
                            if (container.FallbackProvider != null)
                            {
                                foreach (var error in container.FallbackProvider.ValidateBinding(context))
                                {
                                    yield return(error);
                                }
                            }
                            else
                            {
                                yield return(new ZenjectResolveException(
                                                 "Could not find required dependency with type '{0}'{1} \nObject graph:\n{2}"
                                                 .Fmt(
                                                     context.MemberType.Name(),
                                                     (context.ObjectType == null ? "" : " when injecting into '{0}'".Fmt(context.ObjectType.Name())),
                                                     context.GetObjectGraphString())));
                            }
                        }
                        else
                        {
                            yield return(new ZenjectResolveException(
                                             "Found multiple matches when only one was expected for dependency with type '{0}'{1} \nObject graph:\n{2}"
                                             .Fmt(
                                                 context.MemberType.Name(),
                                                 (context.ObjectType == null ? "" : " when injecting into '{0}'".Fmt(context.ObjectType.Name())),
                                                 context.GetObjectGraphString())));
                        }
                    }
                }
            }
        }
Esempio n. 20
0
        public DiContainer CreateSubContainer(List <TypeValuePair> args, InjectContext context)
        {
            // We can't really support arguments if we are using the cached value since
            // the arguments might change when called after the first time
            Assert.IsEmpty(args);

            if (_subContainer == null)
            {
                Assert.That(!_isLookingUp,
                            "Found unresolvable circular dependency when looking up sub container!  Object graph:\n {0}", context.GetObjectGraphString());
                _isLookingUp  = true;
                _subContainer = _subCreator.CreateSubContainer(new List <TypeValuePair>(), context);
                _isLookingUp  = false;
                Assert.IsNotNull(_subContainer);
            }

            return(_subContainer);
        }
Esempio n. 21
0
        public IList ResolveAll(InjectContext context)
        {
            // Note that different types can map to the same provider (eg. a base type to a concrete class and a concrete class to itself)

            var matches = GetProviderMatchesInternal(context).ToList();

            if (matches.Any())
            {
                return(ReflectionUtil.CreateGenericList(
                           context.MemberType, matches.Select(x => x.GetInstance(context)).ToArray()));
            }

            if (!context.Optional)
            {
                if (_fallbackProvider != null)
                {
                    var listType   = typeof(List <>).MakeGenericType(context.MemberType);
                    var subContext = context.ChangeMemberType(listType);

                    return((IList)_fallbackProvider.GetInstance(subContext));
                }

                throw new ZenjectResolveException(
                          "Could not find required dependency with type '" + context.MemberType.Name() + "' \nObject graph:\n" + context.GetObjectGraphString());
            }

            return(ReflectionUtil.CreateGenericList(context.MemberType, new object[] {}));
        }
        public override object GetInstance(InjectContext context)
        {
            Assert.That(_componentType.DerivesFromOrEqual(context.MemberType));

            if (_instance == null)
            {
                Assert.That(!_container.AllowNullBindings,
                            "Tried to instantiate a MonoBehaviour with type '{0}' during validation. Object graph: {1}", _componentType, context.GetObjectGraphString());

                _instance = _gameObject.AddComponent(_componentType);
                Assert.That(_instance != null);

                _container.Inject(_instance);
            }

            return(_instance);
        }
Esempio n. 23
0
        public static IEnumerable<ZenjectResolveException> ValidateContract(DiContainer container, InjectContext context)
        {
            var matches = container.GetProviderMatches(context);

            if (matches.Count == 1)
            {
                foreach (var error in matches.Single().ValidateBinding(context))
                {
                    yield return error;
                }
            }
            else
            {
                if (ReflectionUtil.IsGenericList(context.MemberType))
                {
                    var subContext = context.ChangeMemberType(context.MemberType.GetGenericArguments().Single());

                    matches = container.GetProviderMatches(subContext);

                    if (matches.IsEmpty())
                    {
                        if (!context.Optional)
                        {
                            if (container.FallbackProvider != null)
                            {
                                foreach (var error in container.FallbackProvider.ValidateBinding(context))
                                {
                                    yield return error;
                                }
                            }
                            else
                            {
                                yield return new ZenjectResolveException(
                                    "Could not find dependency with type 'List<{0}>'{1}.  If the empty list is also valid, you can allow this by using the [InjectOptional] attribute.' \nObject graph:\n{2}"
                                    .Fmt(
                                        subContext.MemberType.Name(),
                                        (context.ObjectType == null ? "" : " when injecting into '{0}'".Fmt(context.ObjectType.Name())),
                                        context.GetObjectGraphString()));
                            }
                        }
                    }
                    else
                    {
                        foreach (var match in matches)
                        {
                            foreach (var error in match.ValidateBinding(context))
                            {
                                yield return error;
                            }
                        }
                    }
                }
                else
                {
                    if (!context.Optional)
                    {
                        if (matches.IsEmpty())
                        {
                            if (container.FallbackProvider != null)
                            {
                                foreach (var error in container.FallbackProvider.ValidateBinding(context))
                                {
                                    yield return error;
                                }
                            }
                            else
                            {
                                yield return new ZenjectResolveException(
                                    "Could not find required dependency with type '{0}'{1} \nObject graph:\n{2}"
                                    .Fmt(
                                        context.MemberType.Name(),
                                        (context.ObjectType == null ? "" : " when injecting into '{0}'".Fmt(context.ObjectType.Name())),
                                        context.GetObjectGraphString()));
                            }
                        }
                        else
                        {
                            yield return new ZenjectResolveException(
                                "Found multiple matches when only one was expected for dependency with type '{0}'{1} \nObject graph:\n{2}"
                                .Fmt(
                                    context.MemberType.Name(),
                                    (context.ObjectType == null ? "" : " when injecting into '{0}'".Fmt(context.ObjectType.Name())),
                                    context.GetObjectGraphString()));
                        }
                    }
                }
            }
        }
Esempio n. 24
0
        public static IEnumerable<ZenjectResolveException> ValidateObjectGraph(
            DiContainer container, Type concreteType, InjectContext currentContext, params Type[] extras)
        {
            var typeInfo = TypeAnalyzer.GetInfo(concreteType);
            var extrasList = extras.ToList();

            foreach (var dependInfo in typeInfo.AllInjectables)
            {
                Assert.IsEqual(dependInfo.ObjectType, concreteType);

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

                var context = dependInfo.CreateInjectContext(container, currentContext, 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()), currentContext.GetObjectGraphString()));
            }
        }
Esempio n. 25
0
        // Same as Instantiate except you can pass in null value
        // however the type for each parameter needs to be explicitly provided in this case
        public object InstantiateExplicit(
            Type concreteType, List <TypeValuePair> extraArgMap, InjectContext currentContext)
        {
            using (ProfileBlock.Start("Zenject.Instantiate({0})", concreteType))
            {
                if (_instantiatesInProgress.Contains(concreteType))
                {
                    throw new ZenjectResolveException(
                              "Circular dependency detected! \nObject graph:\n" + concreteType.Name() + "\n" + currentContext.GetObjectGraphString());
                }

                _instantiatesInProgress.Push(concreteType);
                try
                {
                    return(InstantiateInternal(concreteType, extraArgMap, currentContext));
                }
                finally
                {
                    Assert.That(_instantiatesInProgress.Peek() == concreteType);
                    _instantiatesInProgress.Pop();
                }
            }
        }
        public override object GetInstance(InjectContext context)
        {
            Assert.That(_componentType.DerivesFromOrEqual(context.MemberType));

            if (_instance == null)
            {
                Assert.That(!_container.IsValidating,
                            "Tried to instantiate a MonoBehaviour with type '{0}' during validation. Object graph: {1}", _componentType, context.GetObjectGraphString());

                // Note that we always want to cache _container instead of using context.Container
                // since for singletons, the container they are accessed from should not determine
                // the container they are instantiated with
                // Transients can do that but not singletons

                _instance = _gameObject.AddComponent(_componentType);
                Assert.That(_instance != null);

                _container.Inject(_instance);
            }

            return(_instance);
        }
Esempio n. 27
0
        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);
        }
Esempio n. 28
0
        // Return single instance of requested type or assert
        public object Resolve(InjectContext context)
        {
            // Note that different types can map to the same provider (eg. a base type to a concrete class and a concrete class to itself)

            var providers = GetProviderMatchesInternal(context).ToList();

            if (providers.IsEmpty())
            {
                // If it's a generic list then try matching multiple instances to its generic type
                if (ReflectionUtil.IsGenericList(context.MemberType))
                {
                    var subType    = context.MemberType.GetGenericArguments().Single();
                    var subContext = context.ChangeMemberType(subType);

                    return(ResolveAll(subContext));
                }

                if (!context.Optional)
                {
                    if (_fallbackProvider != null)
                    {
                        return(_fallbackProvider.GetInstance(context));
                    }

                    throw new ZenjectResolveException(
                              "Unable to resolve type '{0}'{1}. \nObject graph:\n{2}"
                              .Fmt(
                                  context.MemberType.Name() + (context.Identifier == null ? "" : " with ID '" + context.Identifier.ToString() + "'"),
                                  (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType.Name())),
                                  context.GetObjectGraphString()));
                }

                return(null);
            }

            ProviderBase provider;

            if (providers.Count > 1)
            {
                // If we find multiple providers and we are looking for just one, then
                // choose the one with a condition before giving up and throwing an exception
                // This is nice because it allows us to bind a default and then override with conditions
                provider = providers.Where(x => x.Condition != null).OnlyOrDefault();

                if (provider == null)
                {
                    throw new ZenjectResolveException(
                              "Found multiple matches when only one was expected for type '{0}'{1}. \nObject graph:\n {2}"
                              .Fmt(
                                  context.MemberType.Name(),
                                  (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType.Name())),
                                  context.GetObjectGraphString()));
                }
            }
            else
            {
                provider = providers.Single();
            }

            return(provider.GetInstance(context));
        }