internal PropertyValue(PropertyPath path, int index, MemberInfo member) { this.index = index; Path = path; var ot = FastType.GetType(member.DeclaringType); Member = ot.DeclaredMembers[member.Name]; }
/// <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); } } }
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; } } } }