private void HandleField( PropertyInfo f, IFieldAttribute a, Type t )
        {
            if( a is PersistentFieldAttribute )
                                                {
                                                                PersistentFieldAttribute attribute = a as PersistentFieldAttribute;
                                                                string tablename = attribute.Name;

                                                                this.Context.AddChild( new PersistentFieldMap()
                                                                {
                                                                                Field = f,
                                                                                ChildReturnType = attribute.ChildReturnType ?? f.PropertyType,
                                                                                Cascade = attribute.Cascade,
                                                                                Lazy = ( attribute.Loading == Loading.Active ? false : true ),
                                                                                Linked = attribute.Linked
                                                                }
                                                                .WithBehavior( attribute.Behavior )
                                                                .WithLinkedTable( attribute.LinkName )
                                                                .WithParentKeyColumn( attribute.LinkLeft )
                                                                .WithChildKeyColumn( attribute.LinkRight )
                                                                .WithTable( tablename ) );
                                                }
                                                else if( a is FieldAttribute )
                                                {
                                                                FieldAttribute attribute = a as FieldAttribute;

                                                                FieldMap fm = new FieldMap()
                                                                {
                                                                                Field = f,
                                                                                Behavior = attribute.Behavior,
                                                                                Cascade = attribute.Cascade,
                                                                                DefaultValue = attribute.DefaultValue,
                                                                                MappingType = attribute.MappingType,
                                                                                Name = attribute.Name,
                                                                                Parent = attribute.Parent,
                                                                                Static = attribute.IsStatic,
                                                                                AllowNull = attribute.AllowNull
                                                                };

                                                                switch( attribute.MappingType )
                                                                {
                                                                                case FieldMappingType.ForeignKey: { this.HandleForeignKey( fm ); break; }
                                                                                case FieldMappingType.ManagedPrimaryKey:
                                                                                case FieldMappingType.PrimaryKey: { this.Context.SetPrimaryKey( fm, ( ( PrimaryKeyAttribute )attribute ).UnsavedValue ); break; }
                                                                                case FieldMappingType.PrimaryForeignKey: { this.HandlePrimaryForeignKey( fm ); break; }
                                                                                case FieldMappingType.Reference: { this.Context.AddReferencedField( fm ); break; }
                                                                                case FieldMappingType.Value: { this.Context.AddField( fm ); break; }
                                                                }

                                                                EncryptedAttribute encrypted = Utility.GetCustomFieldAttribute<EncryptedAttribute>( f );
                                                                if( encrypted.NotNull() ) fm.WithEncryption( encrypted.PrivateKey, encrypted.Algorithm );

                                                }
        }
Пример #2
0
        protected IEnumerable <Expression> CreateFieldExpression(PropertyInfo propertyInfo, IFieldAttribute fieldAttribute, ParameterExpression returnExpression, Expression valueExpression)
        {
            List <Expression> ret = new List <Expression>();

            Regex nullRegex = (fieldAttribute.NullPattern != null) ? new Regex(fieldAttribute.NullPattern) : new Regex(@"^\s*$");

            Expression isNullMatch = Expression.Call(Expression.Constant(nullRegex), typeof(Regex).GetMethod("IsMatch", new[] { typeof(String) }), valueExpression);
            Expression assignedExpression;

            if (fieldAttribute.IsRequired)
            {
                ret.Add(Expression.IfThen(isNullMatch, Expression.Throw(Expression.Constant(new Exception($"Field '{propertyInfo.Name}' cannot be null")))));
            }

            assignedExpression = valueExpression;

            List <Expression> temp = new List <Expression>();

            if (fieldAttribute.ValidationPattern != null)
            {
                Regex validationRegex = new Regex(fieldAttribute.ValidationPattern);

                Expression isValidationMatch = Expression.Call(Expression.Constant(validationRegex), typeof(Regex).GetMethod("IsMatch", new[] { typeof(String) }), valueExpression);

                Expression s = Expression.Call(typeof(String).GetMethod("Format", new[] { typeof(String), typeof(String) }), Expression.Constant($"Field '{propertyInfo.Name}' does not match the required format.\nValue: {{0}}"), valueExpression);

                Expression exception = Expression.New(typeof(Exception).GetConstructor(new[] { typeof(String) }), s);

                temp.Add(Expression.IfThen(Expression.Not(isValidationMatch), Expression.Throw(exception)));
            }

            IEnumerable <Attribute> conversionAttributes = propertyInfo.GetCustomAttributes().Where(attribute => attribute.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IConversionAttribute <>)));

            if (conversionAttributes.Count() > 1)
            {
                throw new Exception(String.Format("Property '{0}' cannot contain multiple conversion attributes."));
            }
            else if (conversionAttributes.Count() == 1)
            {
                assignedExpression = Expression.Convert(Expression.Call(Expression.Constant(conversionAttributes.First()), conversionAttributes.First().GetType().GetMethod("Convert", new[] { typeof(String) }), assignedExpression), propertyInfo.PropertyType);
            }
            else if (propertyInfo.PropertyType.IsEnum || (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>) && propertyInfo.PropertyType.GetGenericArguments()[0].IsEnum))
            {
                Type enumType = (propertyInfo.PropertyType.IsEnum) ? propertyInfo.PropertyType : propertyInfo.PropertyType.GetGenericArguments()[0];

                assignedExpression = Expression.Call(assignedExpression, typeof(String).GetMethod("Replace", new[] { typeof(String), typeof(String) }), Expression.Constant(" "), Expression.Constant(""));
                assignedExpression = Expression.Call(assignedExpression, typeof(String).GetMethod("Replace", new[] { typeof(String), typeof(String) }), Expression.Constant("_"), Expression.Constant(""));
                assignedExpression = Expression.Call(assignedExpression, typeof(String).GetMethod("Replace", new[] { typeof(String), typeof(String) }), Expression.Constant("&"), Expression.Constant(""));

                assignedExpression = Expression.Convert(Expression.Call(typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(String), typeof(Boolean) }), Expression.Constant(enumType), assignedExpression, Expression.Constant(true)), propertyInfo.PropertyType);
            }
            else if (propertyInfo.PropertyType != typeof(String))
            {
                // Attempt to find a "Parse" method to convert
                MethodInfo parseMethod = propertyInfo.PropertyType.GetMethod("Parse", new[] { typeof(String) });

                if (parseMethod == null)
                {
                    throw new Exception($"No '{propertyInfo.PropertyType}.Parse(String)' method was found to use for conversion.");
                }

                assignedExpression = Expression.Call(parseMethod, assignedExpression);
            }

            temp.Add(Expression.Assign(Expression.Property(returnExpression, propertyInfo), assignedExpression));

            if (fieldAttribute.IsRequired)
            {
                ret.AddRange(temp);
            }
            else
            {
                ret.Add(Expression.IfThenElse(isNullMatch, Expression.Assign(Expression.Property(returnExpression, propertyInfo), Expression.Convert(Expression.Constant(null), propertyInfo.PropertyType)), Expression.Block(temp)));
            }

            return(ret);
        }
Пример #3
0
        private SR.FieldInfo GetTargetField(IFieldAttribute attr, Type targetType, SR.FieldInfo injectionField)
        {
            var fieldName = !String.IsNullOrEmpty(attr.Name) ? attr.Name : injectionField.Name;
            var foundField = FindMatchingFieldByName(targetType, injectionField, fieldName);

            if (attr is FieldAddInjectionAttribute)
            {
                if (foundField != null)
                    throw new InvalidOperationException(targetType.FullName + "." + fieldName + " is duplicate");
            }
            else
            {
                if (foundField == null)
                    throw new InvalidOperationException(targetType.FullName + "." + fieldName + " not found");
            }

            return foundField;
        }
Пример #4
0
        private static List <Expression> CreateFieldExpression(PropertyInfo propertyInfo, IFieldAttribute fieldAttribute, ParameterExpression returnExpression, Expression valueExpression)
        {
            List <Expression> ret = new List <Expression>();

            Regex nullRegex = (fieldAttribute.NullPattern != null) ? new Regex(fieldAttribute.NullPattern) : new Regex(@"^\s*$");

            Expression isNullMatch        = Expression.Call(Expression.Constant(nullRegex), typeof(Regex).GetMethod("IsMatch", new[] { typeof(string) }) ?? throw new InvalidOperationException(), valueExpression);
            Expression assignedExpression = valueExpression;

            if (fieldAttribute.IsRequired)
            {
                ret.Add(Expression.IfThen(isNullMatch, Expression.Throw(Expression.Constant(new Exception($"Field '{propertyInfo.Name}' cannot be null")))));
            }

            List <Expression> temp = new List <Expression>();

            if (fieldAttribute.ValidationPattern != null)
            {
                Regex validationRegex = new Regex(fieldAttribute.ValidationPattern);

                Expression isValidationMatch = Expression.Call(Expression.Constant(validationRegex), typeof(Regex).GetMethod("IsMatch", new[] { typeof(String) }) ?? throw new InvalidOperationException(), valueExpression);

                Expression s = Expression.Call(typeof(String).GetMethod("Format", new[] { typeof(String), typeof(String) }) ?? throw new InvalidOperationException(), Expression.Constant($"Field '{propertyInfo.Name}' does not match the required format.\nValue: {{0}}"), valueExpression);

                Expression exception = Expression.New(typeof(Exception).GetConstructor(new[] { typeof(String) }) ?? throw new InvalidOperationException(), s);

                temp.Add(Expression.IfThen(Expression.Not(isValidationMatch), Expression.Throw(exception)));
            }

            IEnumerable <Attribute> conversionAttributes = propertyInfo.GetCustomAttributes().Where(attribute => attribute.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IConversionAttribute <>))).ToArray();


            if (conversionAttributes.Count() > 1)
            {
                throw new Exception($"Property '{propertyInfo}' cannot contain multiple conversion attributes.");
            }
            else if (conversionAttributes.Count() == 1)
            {
                assignedExpression = Expression.Convert(Expression.Call(Expression.Constant(conversionAttributes.First()), conversionAttributes.First().GetType().GetMethod("Convert", new[] { typeof(String) }) ?? throw new InvalidOperationException(), assignedExpression), propertyInfo.PropertyType);
            }
            else if (propertyInfo.PropertyType.IsEnum || (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>) && propertyInfo.PropertyType.GetGenericArguments()[0].IsEnum))
            {
                Type enumType = (propertyInfo.PropertyType.IsEnum) ? propertyInfo.PropertyType : propertyInfo.PropertyType.GetGenericArguments()[0];

                assignedExpression = Expression.Call(assignedExpression, typeof(String).GetMethod("Replace", new[] { typeof(String), typeof(String) }) ?? throw new InvalidOperationException(), Expression.Constant(" "), Expression.Constant(""));
                assignedExpression = Expression.Call(assignedExpression, typeof(String).GetMethod("Replace", new[] { typeof(String), typeof(String) }) ?? throw new InvalidOperationException(), Expression.Constant("_"), Expression.Constant(""));
                assignedExpression = Expression.Call(assignedExpression, typeof(String).GetMethod("Replace", new[] { typeof(String), typeof(String) }) ?? throw new InvalidOperationException(), Expression.Constant("&"), Expression.Constant(""));
                assignedExpression = Expression.Call(assignedExpression, typeof(String).GetMethod("Replace", new[] { typeof(String), typeof(String) }) ?? throw new InvalidOperationException(), Expression.Constant("-"), Expression.Constant(""));

                if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    assignedExpression = Expression.Convert(Expression.Call(typeof(StreamParser <TRecord>).GetMethod("ParseEnumCaseIgnored").MakeGenericMethod(Nullable.GetUnderlyingType(propertyInfo.PropertyType)), Expression.Constant(propertyInfo.Name), assignedExpression), propertyInfo.PropertyType);
                }
                else
                {
                    assignedExpression = Expression.Call(typeof(StreamParser <TRecord>).GetMethod("ParseEnumCaseIgnored").MakeGenericMethod(propertyInfo.PropertyType), Expression.Constant(propertyInfo.Name), assignedExpression);
                }
            }
            else if (propertyInfo.PropertyType != typeof(String))
            {
                Type conversionType = propertyInfo.PropertyType;

                // If this is a Nullable<?> type then we need to extract the inner type to find the parse method;
                if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    conversionType = propertyInfo.PropertyType.GetGenericArguments()[0];
                }

                // Attempt to find a "Parse" method to convert
                MethodInfo parseMethod = conversionType.GetMethod("Parse", new[] { typeof(String) });

                if (parseMethod == null)
                {
                    throw new Exception($"No '{propertyInfo.PropertyType}.Parse(String)' method was found to use for conversion.");
                }

                assignedExpression = Expression.Call(parseMethod, assignedExpression);

                if (conversionType != propertyInfo.PropertyType)
                {
                    assignedExpression = Expression.Convert(assignedExpression, propertyInfo.PropertyType);
                }
            }

            temp.Add(Expression.Assign(Expression.Property(returnExpression, propertyInfo), assignedExpression));

            if (fieldAttribute.IsRequired)
            {
                ret.AddRange(temp);
            }
            else
            {
                ret.Add(Expression.IfThenElse(isNullMatch, Expression.Assign(Expression.Property(returnExpression, propertyInfo), Expression.Convert(Expression.Constant(null), propertyInfo.PropertyType)), Expression.Block(temp)));
            }

            return(ret);
        }