Пример #1
0
        private void GetDataFields(Type type, IDictionary <string, IDataField> fields, INestedDataField parent)
        {
            MemberInfo[] members = type.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetField |
                                                   BindingFlags.SetProperty);
            int length = members.Length;
            Dictionary <MemberInfo, IGetterSetter> dictionary1 = length >= 80 || !type.IsClass
                ? (Dictionary <MemberInfo, IGetterSetter>)null
                : AccessorMgr.GetOrCreateAccessors(type);

            foreach (MemberInfo index1 in members)
            {
                if (!index1.IsReadonly() && index1.GetCustomAttributes <NotPersistentAttribute>().Length <= 0)
                {
                    PersistentAttribute attr =
                        ((IEnumerable <DBAttribute>)index1.GetCustomAttributes <DBAttribute>())
                        .Where <DBAttribute>((Func <DBAttribute, bool>)(attribute => attribute is PersistentAttribute))
                        .FirstOrDefault <DBAttribute>() as PersistentAttribute;
                    if (attr != null || !this.m_Attribute.RequirePersistantAttr)
                    {
                        Type          variableType = index1.GetVariableType();
                        bool          isArray      = variableType.IsArray;
                        Type          type1;
                        string        name;
                        IGetterSetter accessor;
                        IFieldReader  reader;
                        if (attr != null)
                        {
                            Type actualType = attr.ActualType;
                            if ((object)actualType == null)
                            {
                                actualType = index1.GetActualType();
                            }
                            type1 = actualType;
                            name  = attr.Name ?? index1.Name;
                            if (attr.AccessorType != (Type)null)
                            {
                                object instance = Activator.CreateInstance(attr.AccessorType);
                                if (!(instance is IGetterSetter))
                                {
                                    throw new DataHolderException(
                                              "Accessor for Persistent members must be of type IGetterSetter - Found accessor of type {0} for member {1}",
                                              new object[2]
                                    {
                                        (object)instance.GetType(),
                                        (object)index1.GetFullMemberName()
                                    });
                                }
                                accessor = (IGetterSetter)instance;
                            }
                            else
                            {
                                accessor = dictionary1 != null
                                    ? dictionary1[index1]
                                    : (IGetterSetter) new DefaultVariableAccessor(index1);
                            }

                            Type type2 = attr.ReadType;
                            if ((object)type2 == null)
                            {
                                type2 = type1;
                            }
                            reader = Converters.GetReader(type2);
                        }
                        else
                        {
                            type1    = index1.GetActualType();
                            name     = index1.Name;
                            accessor = dictionary1 != null
                                ? dictionary1[index1]
                                : (IGetterSetter) new DefaultVariableAccessor(index1);
                            reader = Converters.GetReader(type1);
                        }

                        if (isArray && (variableType.GetArrayRank() > 1 || type1.IsArray))
                        {
                            throw new DataHolderException(
                                      "Cannot define Type {0} of {1} because its a multi-dimensional Array.", new object[2]
                            {
                                (object)variableType,
                                (object)index1.GetFullMemberName()
                            });
                        }
                        IDataField dataField1;
                        if (reader == null)
                        {
                            if (type.IsAbstract)
                            {
                                throw new DataHolderException(
                                          "Cannot define member \"{0}\" of DataHolder \"{1}\" because it's Type ({2}) is abstract.",
                                          new object[3]
                                {
                                    (object)index1.GetFullMemberName(),
                                    (object)this,
                                    (object)type1.FullName
                                });
                            }
                            IProducer producer = !type1.IsClass
                                ? (IProducer)null
                                : DataHolderDefinition.CreateProducer(type1);
                            if (isArray)
                            {
                                int arrayLengthByAttr = DataHolderDefinition.GetArrayLengthByAttr(attr, index1);
                                NestedArrayDataField nestedArrayDataField = new NestedArrayDataField(this, name,
                                                                                                     accessor, index1, producer,
                                                                                                     DataHolderDefinition.CreateArrayProducer(type1, arrayLengthByAttr),
                                                                                                     arrayLengthByAttr, parent);
                                Dictionary <string, IDataField> dictionary2 =
                                    new Dictionary <string, IDataField>(
                                        (IEqualityComparer <string>)StringComparer.InvariantCultureIgnoreCase);
                                this.GetDataFields(type1, (IDictionary <string, IDataField>)dictionary2,
                                                   (INestedDataField)nestedArrayDataField);
                                foreach (IDataField dataField2 in dictionary2.Values)
                                {
                                    for (int index2 = 0; index2 < nestedArrayDataField.ArrayAccessors.Length; ++index2)
                                    {
                                        NestedArrayAccessor arrayAccessor =
                                            (NestedArrayAccessor)nestedArrayDataField.ArrayAccessors[index2];
                                        IDataField dataField3 =
                                            ((DataFieldBase)dataField2).Copy((INestedDataField)arrayAccessor);
                                        arrayAccessor.InnerFields.Add(dataField3.Name, dataField3);
                                    }
                                }

                                dataField1 = (IDataField)nestedArrayDataField;
                            }
                            else
                            {
                                NestedSimpleDataField nestedSimpleDataField =
                                    new NestedSimpleDataField(this, name, accessor, index1, producer, parent);
                                this.GetDataFields(type1,
                                                   (IDictionary <string, IDataField>)nestedSimpleDataField.InnerFields,
                                                   (INestedDataField)nestedSimpleDataField);
                                if (nestedSimpleDataField.InnerFields.Count == 0)
                                {
                                    throw new DataHolderException(
                                              "Cannot define " + index1.GetFullMemberName() +
                                              " as Nested because it does not have any inner fields.", new object[0]);
                                }
                                dataField1 = (IDataField)nestedSimpleDataField;
                            }
                        }
                        else if (isArray)
                        {
                            int arrayLengthByAttr = DataHolderDefinition.GetArrayLengthByAttr(attr, index1);
                            dataField1 = (IDataField) new FlatArrayDataField(this, name, accessor, index1,
                                                                             arrayLengthByAttr, DataHolderDefinition.CreateArrayProducer(type1, arrayLengthByAttr),
                                                                             parent);
                        }
                        else
                        {
                            dataField1 = (IDataField) new FlatSimpleDataField(this, name, accessor, index1, parent);
                            if (name == this.m_DependingFieldName)
                            {
                                this.m_DependingField = (FlatSimpleDataField)dataField1;
                            }
                        }

                        fields.Add(dataField1.Name, dataField1);
                    }
                }
            }

            if (fields.Count <KeyValuePair <string, IDataField> >() - length == 0)
            {
                throw new ArgumentException("Invalid data Type has no persistent members: " + type.FullName);
            }
        }
Пример #2
0
        private void GetDataFields(Type type, IDictionary <string, IDataField> fields, INestedDataField parent)
        {
            var members =
                type.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetField | BindingFlags.SetProperty);
            var count = members.Length;

            Dictionary <MemberInfo, IGetterSetter> accessors;

            if (count < DynamicMaximumMembers && type.IsClass)
            {
                // only create dynamic accessors if there are less than x members
                accessors = AccessorMgr.GetOrCreateAccessors(type);
            }
            else
            {
                accessors = null;
            }

            foreach (var member in members)
            {
                if (member.IsReadonly())
                {
                    continue;
                }

                if (member.GetCustomAttributes <NotPersistentAttribute>().Length > 0)
                {
                    continue;
                }

                var dbAttrs             = member.GetCustomAttributes <DBAttribute>();
                var persistentAttribute = dbAttrs.Where(attribute => attribute is PersistentAttribute).FirstOrDefault() as PersistentAttribute;
                if (persistentAttribute == null && m_Attribute.RequirePersistantAttr)
                {
                    // DataHolder only maps fields/properties with PersistantAttribute
                    continue;
                }

                var rawType = member.GetVariableType();
                var isArr   = rawType.IsArray;

                string        varName;
                IGetterSetter accessor;
                IFieldReader  reader;
                Type          memberType;
                if (persistentAttribute != null)
                {
                    // persistent attribute
                    memberType = persistentAttribute.ActualType ?? member.GetActualType();
                    varName    = persistentAttribute.Name ?? member.Name;
                    if (persistentAttribute.AccessorType != null)
                    {
                        var accessorObj = Activator.CreateInstance(persistentAttribute.AccessorType);
                        if (!(accessorObj is IGetterSetter))
                        {
                            throw new DataHolderException("Accessor for Persistent members must be of type IGetterSetter - "
                                                          + "Found accessor of type {0} for member {1}", accessorObj.GetType(), member.GetFullMemberName());
                        }
                        accessor = (IGetterSetter)accessorObj;
                    }
                    else
                    {
                        accessor = accessors != null ? accessors[member] : new DefaultVariableAccessor(member);
                    }
                    reader = Converters.GetReader(persistentAttribute.ReadType ?? memberType);
                }
                else
                {
                    memberType = member.GetActualType();
                    varName    = member.Name;
                    //accessor = new DefaultVariableAccessor(member);
                    accessor = (accessors != null ? accessors[member] : new DefaultVariableAccessor(member));
                    reader   = Converters.GetReader(memberType);
                }

                // check array constraints
                if (isArr)
                {
                    if (rawType.GetArrayRank() > 1 || memberType.IsArray)
                    {
                        throw new DataHolderException("Cannot define Type {0} of {1} because its a multi-dimensional Array.", rawType,
                                                      member.GetFullMemberName());
                    }
                }

                IDataField field;
                if (reader == null)
                {
                    // create reader
                    if (type.IsAbstract)
                    {
                        throw new DataHolderException(
                                  "Cannot define member \"{0}\" of DataHolder \"{1}\" because it's Type ({2}) is abstract.",
                                  member.GetFullMemberName(), this, memberType.FullName);
                    }

                    IProducer producer;
                    if (memberType.IsClass)
                    {
                        producer = CreateProducer(memberType);
                    }
                    else
                    {
                        // value type does not need a producer
                        producer = null;
                    }

                    if (isArr)
                    {
                        // complex (nested) type
                        var length      = GetArrayLengthByAttr(persistentAttribute, member);
                        var nestedField = new NestedArrayDataField(this, varName, accessor, member,
                                                                   producer, CreateArrayProducer(memberType, length), length, parent);

                        var dataFields = new Dictionary <string, IDataField>(StringComparer.InvariantCultureIgnoreCase);
                        //Console.WriteLine("Getting field for: " + nestedField);

                        GetDataFields(memberType, dataFields, nestedField);
                        foreach (var dataField in dataFields.Values)
                        {
                            for (var i = 0; i < nestedField.ArrayAccessors.Length; i++)
                            {
                                var arrAccessor = (NestedArrayAccessor)nestedField.ArrayAccessors[i];
                                var newField    = ((DataFieldBase)dataField).Copy(arrAccessor);
                                arrAccessor.InnerFields.Add(newField.Name, newField);
                            }
                        }

                        field = nestedField;
                    }
                    else
                    {
                        // simple nested type
                        var nestedField = new NestedSimpleDataField(this, varName, accessor, member, producer, parent);
                        //Console.WriteLine("Getting field for: " + nestedField);

                        GetDataFields(memberType, nestedField.InnerFields, nestedField);
                        if (nestedField.InnerFields.Count == 0)
                        {
                            throw new DataHolderException("Cannot define " + member.GetFullMemberName() +
                                                          " as Nested because it does not have any inner fields.");
                        }
                        else
                        {
                            field = nestedField;
                        }
                    }
                }
                else
                {
                    if (isArr)
                    {
                        //var nestedField = new (this, varName, accessor, member, producer, parent);
                        var length = GetArrayLengthByAttr(persistentAttribute, member);
                        field = new FlatArrayDataField(this, varName, accessor,
                                                       member, length,
                                                       CreateArrayProducer(memberType, length),
                                                       parent);
                    }
                    else
                    {
                        field = new FlatSimpleDataField(this, varName, accessor, member, parent);
                        if (varName == m_DependingFieldName)
                        {
                            m_DependingField = (FlatSimpleDataField)field;
                        }
                    }
                }

                fields.Add(field.Name, field);
            }

            if (fields.Count() - count == 0)
            {
                throw new ArgumentException("Invalid data Type has no persistent members: " + type.FullName);
            }
        }