Exemple #1
0
        public static object ReflectionPropertySet(
            DbConfig config,
            object instance,
            DbClassInfoCache info,
            EagarDataRecord reader,
            ReflectionSetCacheModel cacheModel,
            DbAccessType?dbAccessType)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }

            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            if (reader == null)
            {
                return(instance);
            }

            //Left c# property name and right the object to read from the reader
            //var listofpropertys = new Dictionary<string, object>();

            var propertys = info.Propertys.ToArray();
            var instanceOfFallbackList = new Dictionary <string, object>();
            IDictionary <int, DbPropertyInfoCache> cache = new Dictionary <int, DbPropertyInfoCache>();

            for (var i = 0; i < reader.FieldCount; i++)
            {
                info.Propertys.TryGetValue(info.SchemaMappingDatabaseToLocal(reader.GetName(i)), out var val);
                cache.Add(i, val);
            }

            //var containsKey = cacheModel?.Cache.ContainsKey(info.Type);
            //if (containsKey != true)
            //{
            //	for (var i = 0; i < reader.FieldCount; i++)
            //	{
            //		info.Propertys.TryGetValue(info.SchemaMappingDatabaseToLocal(reader.GetName(i)), out var val);
            //		cache.Add(i, val);
            //	}

            //	if (containsKey == false)
            //	{
            //		cacheModel.Cache[info.Type] = cache;
            //	}
            //}
            //if (containsKey == true)
            //{
            //	cache = cacheModel.Cache[info.Type];
            //}

            for (var i = 0; i < reader.FieldCount; i++)
            {
                var property = cache[i];
                var value    = reader.GetValue(i);

                if (property != null)
                {
                    var attributes = property.Attributes;
                    var valueConverterAttributeModel =
                        attributes.FirstOrDefault(s => s.Attribute is ValueConverterAttribute);

                    //Should the SQL value be converted
                    if (valueConverterAttributeModel != null)
                    {
                        var converter = valueConverterAttributeModel.Attribute as ValueConverterAttribute;
                        //Create the converter and then convert the value before everything else
                        var valueConverter = converter.CreateConverter();
                        value = valueConverter.Convert(value, property.PropertyInfo.PropertyType, converter.Parameter,
                                                       CultureInfo.CurrentCulture);
                    }

                    var xmlAttributeModel =
                        attributes.FirstOrDefault(s => s.Attribute is FromXmlAttribute);

                    //should the Content be considerd as XML text?
                    if (xmlAttributeModel != null)
                    {
                        //Get the XML text and check if its null or empty
                        var xmlStream = value.ToString();
                        if (string.IsNullOrEmpty(xmlStream))
                        {
                            continue;
                        }

                        //Check for List
                        //if this is a list we are expecting other entrys inside
                        if (property.CheckForListInterface())
                        {
                            //target Property is of type list
                            //so expect a xml valid list Take the first element and expect the propertys inside this first element
                            var record = XmlDataRecord.TryParse(xmlStream,
                                                                property.PropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault(), false,
                                                                config);
                            var xmlDataRecords = record.CreateListOfItems();

                            var genericArguments =
                                config.GetOrCreateClassInfoCache(
                                    property.PropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault());
                            var enumerableOfItems =
                                xmlDataRecords.Select(
                                    s => genericArguments
                                    .SetPropertysViaReflection(EagarDataRecord.WithExcludedFields(s),
                                                               dbAccessType, config)).ToList();
                            object castedList;

                            if (genericArguments.Type.IsClass &&
                                genericArguments.Type.GetInterface("INotifyPropertyChanged") != null)
                            {
                                var caster =
                                    typeof(DbCollection <>).MakeGenericType(genericArguments.Type)
                                    .GetConstructor(new[] { typeof(IEnumerable) });
                                castedList = caster.Invoke(new object[] { enumerableOfItems });
                            }
                            else
                            {
                                var caster =
                                    typeof(NonObservableDbCollection <>).MakeGenericType(genericArguments.Type)
                                    .GetConstructor(new[] { typeof(IEnumerable) });
                                castedList = caster.Invoke(new object[] { enumerableOfItems });
                            }

                            property.Setter.Invoke(instance, castedList);
                        }
                        else
                        {
                            var classInfo = config.GetOrCreateClassInfoCache(property
                                                                             .PropertyInfo
                                                                             .PropertyType);

                            var xmlDataRecord = XmlDataRecord.TryParse(xmlStream, property.PropertyInfo.PropertyType,
                                                                       true, config);

                            //the t
                            var xmlSerilizedProperty = classInfo.SetPropertysViaReflection(
                                EagarDataRecord.WithExcludedFields(xmlDataRecord), dbAccessType,
                                config);
                            property.Setter.Invoke(instance, xmlSerilizedProperty);
                        }
                    }
                    else if (value is DBNull || value == null)
                    {
                        //property.Setter.Invoke(instance, new object[] {null});
                    }
                    else if (value is IEnumerable <EagarDataRecord> navigationValue)
                    {
                        Type targetType;
                        if (property.CheckForListInterface())
                        {
                            targetType = property.PropertyType.GetElementType();
                            if (targetType == null)
                            {
                                targetType = property.PropertyType.GetGenericArguments().FirstOrDefault();
                            }
                        }
                        else
                        {
                            targetType = property.PropertyType;
                        }

                        var classInfo   = config.GetOrCreateClassInfoCache(targetType);
                        var enumeration = navigationValue.Select(subReader =>
                        {
                            bool created;
                            var source = CreateInstance(classInfo, subReader, out created);
                            if (created)
                            {
                                return(source);
                            }
                            return(ReflectionPropertySet(config, source, classInfo, subReader, cacheModel, dbAccessType));
                        }).ToArray();

                        if (property.CheckForListInterface())
                        {
                            var caster =
                                typeof(DbCollection <>).MakeGenericType(targetType)
                                .GetConstructor(new[] { typeof(IEnumerable) });
                            var castedList = caster.Invoke(new object[] { enumeration });
                            property.Setter.Invoke(instance, castedList);
                        }
                        else
                        {
                            property.Setter.Invoke(instance, enumeration.FirstOrDefault());
                        }
                    }
                    else
                    {
                        object changedType = value;
                        if (property.PropertyType.IsInstanceOfType(value))
                        {
                            changedType = value;
                        }
                        else
                        {
                            if (!DataConverterExtensions.ChangeType(ref changedType, property.PropertyInfo.PropertyType))
                            {
                                continue;
                            }
                        }

                        //if (value.GetType() != property.PropertyInfo.PropertyType)
                        //{
                        //	changedType = DataConverterExtensions.ChangeType(value, property.PropertyInfo.PropertyType);
                        //}
                        //else
                        //{
                        //	changedType = value;
                        //}

                        property.Setter.Invoke(instance, changedType);
                    }
                }
                //This variable is null if we tried to find a property with the LoadNotImplimentedDynamicAttribute but did not found it
                else if (instanceOfFallbackList != null)
                {
                    //no property found Look for LoadNotImplimentedDynamicAttribute property to include it

                    if (instanceOfFallbackList.Any())
                    {
                        instanceOfFallbackList.Add(reader.GetName(i), value);
                    }
                    else
                    {
                        var maybeFallbackProperty =
                            propertys.FirstOrDefault(
                                s => s.Value.Attributes.Any(e => e.Attribute is LoadNotImplimentedDynamicAttribute));
                        if (maybeFallbackProperty.Value != null)
                        {
                            instanceOfFallbackList =
                                (Dictionary <string, object>)maybeFallbackProperty.Value.Getter.Invoke(instance);
                            if (instanceOfFallbackList == null)
                            {
                                instanceOfFallbackList = new Dictionary <string, object>();
                                maybeFallbackProperty.Value.Setter.Invoke(instance, instanceOfFallbackList);
                            }

                            instanceOfFallbackList.Add(reader.GetName(i), value);
                        }
                        else
                        {
                            instanceOfFallbackList = null;
                        }
                    }
                }
            }

            //foreach (var item in listofpropertys)
            //{
            //	var property = propertys.FirstOrDefault(s => s.PropertyName == item.Key);

            //}
            return(instance);
        }
Exemple #2
0
//		/// <summary>
//		///     Creates a new Instance based on possible Ctor's and the given
//		///     <paramref name="reader" />
//		/// </summary>
//		/// <returns></returns>
//		public object SetPropertysViaReflection(DbClassInfoCache type, EagarDataRecord reader,
//			Dictionary<int, DbPropertyInfoCache> mapping)
//		{
//			bool created;
//			var source = CreateInstance(type, reader, out created);
//			if (created)
//			{
//				return source;
//			}

//#pragma warning disable 618
//			return ReflectionPropertySet(Config, source, type, reader, mapping, DbAccessType);
//#pragma warning restore 618
//		}

//		/// <summary>
//		///     Creates an instance based on a Ctor injection or Reflection loading
//		///     or when using a MsCoreLib type direct enumeration
//		/// </summary>
//		/// <returns></returns>
//		public static object CreateInstance(DbClassInfoCache classInfo,
//			EagarDataRecord reader)
//		{
//			bool loaded;
//			return CreateInstance(classInfo, reader, out loaded);
//		}

        /// <summary>
        ///     Creates an instance based on a Ctor injection or Reflection loading
        ///     or when using a MsCoreLib type direct enumeration
        /// </summary>
        /// <returns></returns>
        public static object CreateInstance(DbClassInfoCache classInfo,
                                            EagarDataRecord reader,
                                            out bool fullLoaded,
                                            DbAccessType?accessType = null)
        {
            reader.WrapNulls = true;

            if (classInfo.IsMsCoreFrameworkType && reader.FieldCount == 1)
            {
                fullLoaded = true;
                var plainValue = reader.GetValue(0);

                return(plainValue);
            }

            if (classInfo.Factory != null)
            {
                fullLoaded = classInfo.FullFactory;
                var fullObject = classInfo.Factory(reader);
                return(fullObject);
            }

            var factories = classInfo.Constructors.Where(s =>
                                                         s.Arguments.Count == 1 &&
                                                         s.Arguments.First().Type.IsAssignableFrom(typeof(EagarDataRecord)))
                            .ToArray();

            var constructor = factories.FirstOrDefault(s =>
                                                       s.Attributes.Any(f =>
                                                                        f.Attribute is ObjectFactoryMethodAttribute attribute
                                                                        &&
                                                                        (!accessType.HasValue ||
                                                                         attribute.TargetDatabase ==
                                                                         accessType.Value))) ??
                              factories.FirstOrDefault();

            //maybe single ctor with param

            if (constructor != null)
            {
                if (constructor.Arguments.Count == 1 &&
                    constructor.Arguments.First().Type.IsAssignableFrom(typeof(EagarDataRecord)))
                {
                    classInfo.FullFactory = true;
                    classInfo.Factory     = s => constructor.Invoke(new object[] { s });
                    return(CreateInstance(classInfo, reader, out fullLoaded, accessType));
                }
            }
            else
            {
                //check for a Factory method
                var factory =
                    classInfo.Mehtods
                    .FirstOrDefault(s => s.Attributes.Any(f => f.Attribute is ObjectFactoryMethodAttribute));

                if (factory != null)
                {
                    if (factory.MethodInfo.IsStatic)
                    {
                        var methodInfo = factory.MethodInfo as MethodInfo;
                        if (methodInfo != null)
                        {
                            var returnType = methodInfo.ReturnParameter;

                            if (returnType != null && returnType.ParameterType == classInfo.Type)
                            {
                                if (factory.Arguments.Count == 1 &&
                                    factory.Arguments.First().Type.IsAssignableFrom(typeof(EagarDataRecord)))
                                {
                                    classInfo.FullFactory = true;
                                    classInfo.Factory     = s => factory.Invoke(new object[] { reader });
                                    return(CreateInstance(classInfo, reader, out fullLoaded, accessType));
                                }
                            }
                        }
                    }
                }
            }

            var emptyCtor = classInfo.Constructors.FirstOrDefault(f => !f.Arguments.Any());

            if (emptyCtor == null)
            {
                throw new NotSupportedException(
                          "You have to define ether an ObjectFactoryMethod as static or constructor with and IDataReader or an constructor without any arguments");
            }

            classInfo.FullFactory = false;
            classInfo.Factory     = s => emptyCtor.Invoke();
            return(CreateInstance(classInfo, reader, out fullLoaded, accessType));
        }