Пример #1
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public static bool TryGetMemberInfo(
            [NotNull] this IPropertyBase propertyBase,
            bool forConstruction,
            bool forSet,
            out MemberInfo memberInfo,
            out string errorMessage)
        {
            memberInfo   = null;
            errorMessage = null;

            var propertyInfo   = propertyBase.PropertyInfo;
            var fieldInfo      = propertyBase.FieldInfo;
            var setterProperty = propertyInfo?.FindSetterProperty();
            var getterProperty = propertyInfo?.FindGetterProperty();

            var isCollectionNav = (propertyBase as INavigation)?.IsCollection() == true;
            var hasField        = fieldInfo != null;
            var hasSetter       = setterProperty != null;
            var hasGetter       = getterProperty != null;

            var mode = propertyBase.GetPropertyAccessMode();

            if (forConstruction)
            {
                if (mode == PropertyAccessMode.Field ||
                    mode == PropertyAccessMode.FieldDuringConstruction)
                {
                    if (hasField)
                    {
                        memberInfo = fieldInfo;
                        return(true);
                    }

                    if (isCollectionNav)
                    {
                        return(true);
                    }

                    errorMessage = GetNoFieldErrorMessage(propertyBase);
                    return(false);
                }

                if (mode == PropertyAccessMode.Property)
                {
                    if (hasSetter)
                    {
                        memberInfo = setterProperty;
                        return(true);
                    }

                    if (isCollectionNav)
                    {
                        return(true);
                    }

                    errorMessage = hasGetter
                        ? CoreStrings.NoSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode))
                        : CoreStrings.NoProperty(fieldInfo?.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));

                    return(false);
                }

                if (mode == PropertyAccessMode.PreferField ||
                    mode == PropertyAccessMode.PreferFieldDuringConstruction)
                {
                    if (hasField)
                    {
                        memberInfo = fieldInfo;
                        return(true);
                    }

                    if (hasSetter)
                    {
                        memberInfo = setterProperty;
                        return(true);
                    }
                }

                if (mode == PropertyAccessMode.PreferProperty)
                {
                    if (hasSetter)
                    {
                        memberInfo = setterProperty;
                        return(true);
                    }

                    if (hasField)
                    {
                        memberInfo = fieldInfo;
                        return(true);
                    }
                }

                if (isCollectionNav)
                {
                    return(true);
                }

                errorMessage = CoreStrings.NoFieldOrSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
                return(false);
            }

            if (forSet)
            {
                if (mode == PropertyAccessMode.Field)
                {
                    if (hasField)
                    {
                        memberInfo = fieldInfo;
                        return(true);
                    }

                    if (isCollectionNav)
                    {
                        return(true);
                    }

                    errorMessage = GetNoFieldErrorMessage(propertyBase);
                    return(false);
                }

                if (mode == PropertyAccessMode.Property)
                {
                    if (hasSetter)
                    {
                        memberInfo = setterProperty;
                        return(true);
                    }

                    if (isCollectionNav)
                    {
                        return(true);
                    }

                    errorMessage = hasGetter
                        ? CoreStrings.NoSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode))
                        : CoreStrings.NoProperty(fieldInfo?.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));

                    return(false);
                }

                if (mode == PropertyAccessMode.PreferField)
                {
                    if (hasField)
                    {
                        memberInfo = fieldInfo;
                        return(true);
                    }

                    if (hasSetter)
                    {
                        memberInfo = setterProperty;
                        return(true);
                    }
                }

                if (mode == PropertyAccessMode.PreferProperty ||
                    mode == PropertyAccessMode.FieldDuringConstruction ||
                    mode == PropertyAccessMode.PreferFieldDuringConstruction)
                {
                    if (hasSetter)
                    {
                        memberInfo = setterProperty;
                        return(true);
                    }

                    if (hasField)
                    {
                        memberInfo = fieldInfo;
                        return(true);
                    }
                }

                if (isCollectionNav)
                {
                    return(true);
                }

                errorMessage = CoreStrings.NoFieldOrSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
                return(false);
            }

            // forGet
            if (mode == PropertyAccessMode.Field)
            {
                if (hasField)
                {
                    memberInfo = fieldInfo;
                    return(true);
                }

                errorMessage = GetNoFieldErrorMessage(propertyBase);
                return(false);
            }

            if (mode == PropertyAccessMode.Property)
            {
                if (hasGetter)
                {
                    memberInfo = getterProperty;
                    return(true);
                }

                errorMessage = hasSetter
                    ? CoreStrings.NoGetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode))
                    : CoreStrings.NoProperty(fieldInfo?.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));

                return(false);
            }

            if (mode == PropertyAccessMode.PreferField)
            {
                if (hasField)
                {
                    memberInfo = fieldInfo;
                    return(true);
                }

                if (hasGetter)
                {
                    memberInfo = getterProperty;
                    return(true);
                }
            }

            if (mode == PropertyAccessMode.PreferProperty ||
                mode == PropertyAccessMode.FieldDuringConstruction ||
                mode == PropertyAccessMode.PreferFieldDuringConstruction)
            {
                if (hasGetter)
                {
                    memberInfo = getterProperty;
                    return(true);
                }

                if (hasField)
                {
                    memberInfo = fieldInfo;
                    return(true);
                }
            }

            errorMessage = CoreStrings.NoFieldOrGetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
            return(false);
        }
Пример #2
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public static bool TryGetMemberInfo(
            [NotNull] this IPropertyBase propertyBase,
            bool forConstruction,
            bool forSet,
            [CanBeNull] out MemberInfo memberInfo,
            [CanBeNull] out string errorMessage)
        {
            memberInfo   = null;
            errorMessage = null;

            var propertyInfo    = propertyBase.PropertyInfo;
            var fieldInfo       = propertyBase.FieldInfo;
            var isCollectionNav = (propertyBase as INavigation)?.IsCollection() == true;

            var mode = propertyBase.GetPropertyAccessMode();

            if (mode == null ||
                mode == PropertyAccessMode.FieldDuringConstruction)
            {
                if (forConstruction &&
                    fieldInfo != null &&
                    !fieldInfo.IsInitOnly)
                {
                    memberInfo = fieldInfo;
                    return(true);
                }

                if (forConstruction)
                {
                    if (fieldInfo != null)
                    {
                        if (!fieldInfo.IsInitOnly)
                        {
                            memberInfo = fieldInfo;
                            return(true);
                        }

                        if (mode == PropertyAccessMode.FieldDuringConstruction &&
                            !isCollectionNav)
                        {
                            errorMessage = CoreStrings.ReadonlyField(fieldInfo.Name, propertyBase.DeclaringType.DisplayName());
                            return(false);
                        }
                    }

                    if (mode == PropertyAccessMode.FieldDuringConstruction)
                    {
                        if (!isCollectionNav)
                        {
                            errorMessage = CoreStrings.NoBackingField(
                                propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));
                            return(false);
                        }
                        return(true);
                    }
                }

                if (forSet)
                {
                    var setterProperty = propertyInfo?.FindSetterProperty();
                    if (setterProperty != null)
                    {
                        memberInfo = setterProperty;
                        return(true);
                    }

                    if (fieldInfo != null)
                    {
                        if (!fieldInfo.IsInitOnly)
                        {
                            memberInfo = fieldInfo;
                            return(true);
                        }

                        if (!isCollectionNav)
                        {
                            errorMessage = CoreStrings.ReadonlyField(fieldInfo.Name, propertyBase.DeclaringType.DisplayName());
                            return(false);
                        }
                    }

                    if (!isCollectionNav)
                    {
                        errorMessage = CoreStrings.NoFieldOrSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
                        return(false);
                    }

                    return(true);
                }

                var getterPropertyInfo = propertyInfo?.FindGetterProperty();
                if (getterPropertyInfo != null)
                {
                    memberInfo = getterPropertyInfo;
                    return(true);
                }

                if (fieldInfo != null)
                {
                    memberInfo = fieldInfo;
                    return(true);
                }

                errorMessage = CoreStrings.NoFieldOrGetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
                return(false);
            }

            if (mode == PropertyAccessMode.Field)
            {
                if (fieldInfo == null)
                {
                    if (!forSet ||
                        !isCollectionNav)
                    {
                        errorMessage = CoreStrings.NoBackingField(
                            propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));
                        return(false);
                    }
                    return(true);
                }

                if (forSet &&
                    fieldInfo.IsInitOnly)
                {
                    if (!isCollectionNav)
                    {
                        errorMessage = CoreStrings.ReadonlyField(fieldInfo.Name, propertyBase.DeclaringType.DisplayName());
                        return(false);
                    }
                    return(true);
                }

                memberInfo = fieldInfo;
                return(true);
            }

            if (propertyInfo == null)
            {
                errorMessage = CoreStrings.NoProperty(fieldInfo.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));
                return(false);
            }

            if (forSet)
            {
                var setterProperty = propertyInfo.FindSetterProperty();
                if (setterProperty == null &&
                    !isCollectionNav)
                {
                    errorMessage = CoreStrings.NoSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));
                    return(false);
                }

                memberInfo = setterProperty;
                return(true);
            }

            var getterProperty = propertyInfo.FindGetterProperty();

            if (getterProperty == null)
            {
                errorMessage = CoreStrings.NoGetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));
                return(false);
            }

            memberInfo = getterProperty;
            return(true);
        }