public InjectTypeInfo(
     Type type,
     InjectConstructorInfo injectConstructor,
     IReadOnlyList <InjectMethodInfo> injectMethods,
     IReadOnlyList <FieldInfo> injectFields,
     IReadOnlyList <PropertyInfo> injectProperties)
 {
     Type = type;
     InjectConstructor = injectConstructor;
     InjectFields      = injectFields;
     InjectProperties  = injectProperties;
     InjectMethods     = injectMethods;
 }
        public static InjectTypeInfo Analyze(Type type)
        {
            var injectConstructor = default(InjectConstructorInfo);
            var typeInfo          = type.GetTypeInfo();

            // Constructor, single [Inject] constructor -> single most parameters constuctor
            var injectConstructorCount = 0;
            var maxParameters          = -1;

            foreach (var constructorInfo in typeInfo.DeclaredConstructors)
            {
                if (constructorInfo.IsDefined(typeof(InjectAttribute), true))
                {
                    if (++injectConstructorCount > 1)
                    {
                        throw new VContainerException(type, "Type found multiple [Inject] marked constructors, type:" + type.Name);
                    }
                    injectConstructor = new InjectConstructorInfo(constructorInfo);
                }
                else
                {
                    var parameterInfos = constructorInfo.GetParameters();
                    if (parameterInfos.Length > maxParameters)
                    {
                        injectConstructor = new InjectConstructorInfo(constructorInfo, parameterInfos);
                        maxParameters     = parameterInfos.Length;
                    }
                }
            }

            if (injectConstructor == null)
            {
                throw new VContainerException(type, $"Type does not found injectable constructor, type: {type.Name}");
            }

            // Methods, [Inject] Only
            var injectMethods = default(List <InjectMethodInfo>);

            foreach (var methodInfo in type.GetRuntimeMethods())
            {
                if (methodInfo.IsDefined(typeof(InjectAttribute), true))
                {
                    if (injectMethods == null)
                    {
                        injectMethods = new List <InjectMethodInfo>();
                    }
                    injectMethods.Add(new InjectMethodInfo(methodInfo));
                }
            }

            // Fields, [Inject] Only
            var injectFields = default(List <FieldInfo>);

            foreach (var fieldInfo in type.GetRuntimeFields())
            {
                if (fieldInfo.IsDefined(typeof(InjectAttribute), true))
                {
                    if (injectFields == null)
                    {
                        injectFields = new List <FieldInfo>();
                    }
                    injectFields.Add(fieldInfo);
                }
            }

            // Properties, [Inject] only
            var injectProperties = default(List <PropertyInfo>);

            foreach (var propertyInfo in type.GetRuntimeProperties())
            {
                if (propertyInfo.IsDefined(typeof(InjectAttribute), true))
                {
                    if (injectProperties == null)
                    {
                        injectProperties = new List <PropertyInfo>();
                    }
                    injectProperties.Add(propertyInfo);
                }
            }

            return(new InjectTypeInfo(
                       type,
                       injectConstructor,
                       injectMethods,
                       injectFields,
                       injectProperties));
        }
Пример #3
0
        public static InjectTypeInfo Analyze(Type type)
        {
            var injectConstructor = default(InjectConstructorInfo);
            var typeInfo          = type.GetTypeInfo();

            // Constructor, single [Inject] constructor -> single most parameters constuctor
            var annotatedConstructorCount = 0;
            var maxParameters             = -1;

            foreach (var constructorInfo in typeInfo.GetConstructors(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (constructorInfo.IsDefined(typeof(InjectAttribute), false))
                {
                    if (++annotatedConstructorCount > 1)
                    {
                        throw new VContainerException(type, "Type found multiple [Inject] marked constructors, type:" + type.Name);
                    }
                    injectConstructor = new InjectConstructorInfo(constructorInfo);
                }
                else if (annotatedConstructorCount <= 0)
                {
                    var parameterInfos = constructorInfo.GetParameters();
                    if (parameterInfos.Length > maxParameters)
                    {
                        injectConstructor = new InjectConstructorInfo(constructorInfo, parameterInfos);
                        maxParameters     = parameterInfos.Length;
                    }
                }
            }

            if (injectConstructor == null)
            {
                var allowNoConstructor = type.IsEnum;
#if UNITY_2018_4_OR_NEWER
                // It seems that Unity sometimes strips the constructor of Component at build time.
                // In that case, allow null.
                allowNoConstructor |= type.IsSubclassOf(typeof(UnityEngine.Component));
#endif
                if (!allowNoConstructor)
                {
                    throw new VContainerException(type, $"Type does not found injectable constructor, type: {type.Name}");
                }
            }
            // Methods, [Inject] Only
            var injectMethods = default(List <InjectMethodInfo>);
            foreach (var methodInfo in type.GetRuntimeMethods())
            {
                if (methodInfo.IsDefined(typeof(InjectAttribute), true))
                {
                    if (injectMethods == null)
                    {
                        injectMethods = new List <InjectMethodInfo>();
                    }
                    injectMethods.Add(new InjectMethodInfo(methodInfo));
                }
            }

            // Fields, [Inject] Only
            var injectFields = default(List <FieldInfo>);
            foreach (var fieldInfo in type.GetRuntimeFields())
            {
                if (fieldInfo.IsDefined(typeof(InjectAttribute), true))
                {
                    if (injectFields == null)
                    {
                        injectFields = new List <FieldInfo>();
                    }
                    injectFields.Add(fieldInfo);
                }
            }

            // Properties, [Inject] only
            var injectProperties = default(List <PropertyInfo>);
            foreach (var propertyInfo in type.GetRuntimeProperties())
            {
                if (propertyInfo.IsDefined(typeof(InjectAttribute), true))
                {
                    if (injectProperties == null)
                    {
                        injectProperties = new List <PropertyInfo>();
                    }
                    injectProperties.Add(propertyInfo);
                }
            }

            return(new InjectTypeInfo(
                       type,
                       injectConstructor,
                       injectMethods,
                       injectFields,
                       injectProperties));
        }