Esempio n. 1
0
            internal PropertyValue(PropertyPath path, int index, MemberInfo member)
            {
                this.index = index;
                Path       = path;

                var ot = FastType.GetType(member.DeclaringType);

                Member = ot.DeclaredMembers[member.Name];
            }
Esempio n. 2
0
        /// <summary>
        /// Will set all properties marked with <see cref="ImportAttribute"/>. If property is an array or a <see cref="List{T}"/>
        /// It will <see cref="ResolveAll(Type, RequestCache)"/> and set up the array / collection with the result.
        /// </summary>
        /// <param name="instance">The object which property must be resolved.</param>
        /// <param name="cache">A cache for the request so that each instance which are not service is created only once.</param>
        public void ResolveProperties(object instance, RequestCache cache = null)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }
            if (cache == null)
            {
                cache = new RequestCache();
            }

            var ftype = FastType.GetType(instance.GetType());
            var props = (
                from p in ftype.GetRuntimeMembers()
                where !p.IsStatic
                let pi = p.Member.GetCustomAttributes <ImportAttribute>().FirstOrDefault()
                         where pi != null
                         select new { p, pi }
                ).ToList();

            foreach (var item in props)
            {
                var p  = item.p;
                var pi = item.pi;
                if (IsBaseClass(typeof(IEnumerable), p.Type.Type))
                {
                    var t = pi.ImportedType;
                    // T[]
                    if (p.Type.Type.IsArray)
                    {
                        if (t == null)
                        {
                            t = p.Type.Type.GetElementType();
                        }
                        if (!IsBaseClass(p.Type.Type.GetElementType(), t))
                        {
                            throw new NotSupportedException($"Property {instance.GetType().Name}.{p.Name}, can't import {t.Name}");
                        }
                        var objs = FindRegistrations(t, cache).Select(x => Resolve(x, cache)).ToList();
                        var prop = Array.CreateInstance(t, objs.Count);
                        for (int i = 0; i < objs.Count; i++)
                        {
                            prop.SetValue(objs[i], i);
                        }
                        item.p.SetValue(instance, prop);
                    }
                    // List<T>
                    else
                    {
                        if (!IsBaseClass(typeof(IList), p.Type.Type))
                        {
                            throw new InvalidOperationException($"[Import] property {instance.GetType().Name}.{p.Name} must be an array or an IList");
                        }

                        if (t == null)
                        {
                            var ga = p.Type.Type.GenericTypeArguments;
                            if (ga.Length != 1)
                            {
                                throw new NotSupportedException($"[Import] property {instance.GetType().Name}.{p.Name} must be generic or the Import type must be defined");
                            }
                            t = ga[0];
                        }
                        var value = p.GetValue(instance);
                        if (value == null)
                        {
                            if (!CanBeInstantiated(p.Type.Type) || !p.CanSet)
                            {
                                throw new InvalidOperationException($"Can't [Import]{p.Type.Type.Name} for {instance.GetType().Name}.{p.Name}");
                            }
                            value = Create(p.Type.Type, cache);
                            p.SetValue(instance, value);
                        }
                        var list = (IList)value;
                        ForEach(FindRegistrations(t, cache).Select(x => Resolve(x, cache)), x => list.Add(x));
                    }
                }
                else
                {
                    // simple property
                    var o = ResolveAll(pi.ImportedType ?? p.Type.Type, cache).First();
                    item.p.SetValue(instance, o);
                }
            }
        }
Esempio n. 3
0
        private void Initialize(Type type)
        {
            Type        = type;
            IsSupported = !IsIgnored(type);
            if (!IsSupported)
            {
                return;
            }

            Kind     = PrimitiveConverter.GetPrimitiveType(type);
            FastType = FastType.GetType(type);

            switch (Kind)
            {
            case PrimitiveType.None:
            case PrimitiveType.Object:
                break;

            case PrimitiveType.Type:
            case PrimitiveType.String:
            case PrimitiveType.Bytes:
                IsReference = true;
                IsSealed    = true;
                return;

            default:
                return;
            }

            void CaptureName()
            {
                var nattr = type.GetCustomAttribute <SerializationNameAttribute>();

                if (nattr != null)
                {
                    FullName = nattr.FullName;
                    Assembly = nattr.AssemblyName;
                }
                else
                {
                    FullName = type.FullName;
                    if (!FastType.IsMscorlib)
                    {
                        Assembly = type.Assembly.GetName().Name;
                    }
                }
            }

            if (type.IsArray)
            {
                IsReference = true;
                IsSealed    = true;
                IsArray     = true;
                ArrayRank   = type.GetArrayRank();
                Element     = GetType(type.GetElementType());
            }
            else if (type.IsEnum)
            {
                IsEnum  = true;
                Element = GetType(type.GetEnumUnderlyingType());
                CaptureName();
            }
            else if (type.IsGenericParameter)
            {
                IsGenericParameter = true;
                var pargs = type.DeclaringType.GetGenericArguments();
                for (int i = 0; i < pargs.Length; i++)
                {
                    if (pargs[i].Name == type.Name)
                    {
                        GenericParameterIndex = i;
                        break;
                    }
                }
            }
            else
            {
                IsSealed        = type.IsSealed;
                IsReference     = !type.IsValueType;
                Surrogate       = GetSurrogate(type);
                BaseType        = GetType(type.BaseType);
                IsInterface     = type.IsInterface;
                IsAbstract      = type.IsAbstract;
                IsISerializable = typeof(ISerializable).IsBaseClass(type);
                Converter       = GetTypeConverter();

                if (type.IsGenericType)
                {
                    IsGeneric = true;
                    if (type.IsGenericTypeDefinition)
                    {
                        IsGenericTypeDefinition = true;
                        CaptureName();
                    }
                    else
                    {
                        var def = type.GetGenericTypeDefinition();
                        Element    = GetType(def);
                        IsNullable = def == typeof(Nullable <>);
                    }
                    GenericParameters = type.GetGenericArguments()
                                        .Select(x => GetType(x))
                                        .ToList()
                                        .AsReadOnly();
                }
                else
                {
                    CaptureName();
                }

                if (Surrogate == null && !IsInterface)
                {
                    var settings = type.GetCustomAttribute <SerializationSettingsAttribute>() ?? SerializationSettingsAttribute.Defaults;
                    foreach (var m in FastType.DeclaredMembers)
                    {
                        if (m.IsStatic || m.IsOverride)
                        {
                            continue;
                        }
                        var rType = GetType(m.Type.Type);
                        if (!rType.IsSupported)
                        {
                            continue;
                        }
                        if (m.GetAttribute <NotSerializedAttribute>() != null)
                        {
                            continue;
                        }
                        if (m.GetAttribute <SerializedAttribute>() == null)
                        {
                            if (m.IsField && m.IsPublic && !settings.IncludePublicFields)
                            {
                                continue;
                            }
                            if (m.IsField && !m.IsPublic && !settings.IncludePrivateFields)
                            {
                                continue;
                            }
                            if (!m.IsField && m.IsPublic && !settings.IncludePublicProperties)
                            {
                                continue;
                            }
                            if (!m.IsField && !m.IsPublic && !settings.IncludePrivateProperties)
                            {
                                continue;
                            }
                        }
                        if (!m.CanSet && !m.Type.IsReference)
                        {
                            continue;
                        }
                        var name = m.GetAttribute <SerializationMemberNameAttribute>()?.MemberName;
                        Members.Add(new Member(this)
                        {
                            Name          = name ?? m.Name,
                            Type          = rType,
                            RuntimeMember = m,
                        });
                    }

                    var interfaces = type.GetInterfaces();
                    var iDictKV    = interfaces.Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary <,>)).FirstOrDefault();
                    var iColT      = interfaces.Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection <>)).FirstOrDefault();
                    if (settings.IncludeDictionaryInterface && iDictKV != null)
                    {
                        CollectionType = RuntimeCollectionType.IDictionaryKV;
                        Collection1    = GetType(iDictKV.GenericTypeArguments[0]);
                        Collection2    = GetType(iDictKV.GenericTypeArguments[1]);
                    }
                    else if (settings.IncludeListInterface && iColT != null)
                    {
                        CollectionType = RuntimeCollectionType.ICollectionT;
                        Collection1    = GetType(iColT.GenericTypeArguments[0]);
                    }
                    else if (settings.IncludeDictionaryInterface && interfaces.Contains(typeof(IDictionary)))
                    {
                        CollectionType = RuntimeCollectionType.IDictionary;
                    }
                    else if (settings.IncludeListInterface && interfaces.Contains(typeof(IList)))
                    {
                        CollectionType = RuntimeCollectionType.IList;
                    }
                }
            }
        }