Ejemplo n.º 1
0
        /// <summary>
        ///     Internal use Only
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="anon"></param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException">The object is already Initialed. A Change is not allowed</exception>
        public virtual IPropertyInfoCache <TAtt> Init(PropertyInfo propertyInfo, bool anon)
        {
            if (!string.IsNullOrEmpty(PropertyName))
            {
                throw new InvalidOperationException("The object is already Initialed. A Change is not allowed");
            }

            Attributes.Clear();
            if (propertyInfo == null)
            {
                return(this);
            }
            var getMethod = propertyInfo.GetMethod;
            var setMethod = propertyInfo.SetMethod;

            PropertyInfo = propertyInfo;
            PropertyName = propertyInfo.Name;
            PropertyType = propertyInfo.PropertyType;

            if (!anon && (getMethod != null || setMethod != null))
            {
                var isStatic = getMethod != null
                                        ? getMethod.Attributes.HasFlag(MethodAttributes.Static)
                                        : setMethod.Attributes.HasFlag(MethodAttributes.Static);

                var builder = typeof(Expression)
                              .GetMethods()
                              .First(s => s.Name == "Lambda" && s.ContainsGenericParameters);

                if (isStatic)
                {
                    GetterDelegate = typeof(Func <>).MakeGenericType(propertyInfo.PropertyType);
                    SetterDelegate = typeof(Action <>).MakeGenericType(propertyInfo.PropertyType);
                    var accessField = Expression.Property(null, propertyInfo);

                    if (getMethod != null)
                    {
                        var getExpression = builder
                                            .MakeGenericMethod(GetterDelegate)
                                            .Invoke(null, new object[]
                        {
                            accessField, null
                        }) as dynamic;

                        var getterDelegate = getExpression.Compile();
                        Getter = new PropertyHelper <TAtt>(getMethod);
                        ((PropertyHelper <TAtt>)Getter).SetGet(getterDelegate);
                    }
                    if (setMethod != null)
                    {
                        var valueRef = Expression.Parameter(propertyInfo.PropertyType, "newValue");
                        var setter   = Expression.Assign(
                            accessField,
                            valueRef);

                        var setExpression = builder
                                            .MakeGenericMethod(SetterDelegate)
                                            .Invoke(null, new object[]
                        {
                            setter,
                            new[]
                            {
                                valueRef
                            }
                        }) as dynamic;

                        var setterDelegate = setExpression.Compile();
                        Setter = new PropertyHelper <TAtt>(setMethod);
                        ((PropertyHelper <TAtt>)Setter).SetSet(setterDelegate);
                    }
                }
                else
                {
                    GetterDelegate = typeof(Func <,>).MakeGenericType(propertyInfo.DeclaringType, propertyInfo.PropertyType);
                    SetterDelegate = typeof(Func <, ,>).MakeGenericType(propertyInfo.DeclaringType, propertyInfo.PropertyType,
                                                                        propertyInfo.DeclaringType);
                    var thisRef = Expression.Parameter(propertyInfo.DeclaringType, "that");

                    var accessField = Expression.MakeMemberAccess(thisRef, propertyInfo);

                    if (getMethod != null)
                    {
                        var getExpression = builder
                                            .MakeGenericMethod(GetterDelegate)
                                            .Invoke(null, new object[]
                        {
                            accessField,
                            new[] { thisRef }
                        }) as dynamic;

                        var getterDelegate = getExpression.Compile();
                        Getter = new PropertyHelper <TAtt>(getMethod);
                        ((PropertyHelper <TAtt>)Getter).SetGet(getterDelegate);
                    }
                    if (setMethod != null)
                    {
                        var valueRef = Expression.Parameter(propertyInfo.PropertyType, "newValue");
                        var setter   = Expression.Assign(
                            accessField,
                            valueRef);
                        var makeRetunLabel       = Expression.Label(propertyInfo.DeclaringType);
                        var retunLabel           = Expression.Label(makeRetunLabel, Expression.Default(propertyInfo.DeclaringType));
                        var returnMaybeValueType = Expression.Return(makeRetunLabel, thisRef);

                        var setExpression = builder
                                            .MakeGenericMethod(SetterDelegate)
                                            .Invoke(null, new object[]
                        {
                            Expression.Block(setter, returnMaybeValueType, retunLabel),
                            new[] { thisRef, valueRef }
                        }) as dynamic;

                        var setterDelegate = setExpression.Compile();
                        Setter = new PropertyHelper <TAtt>(setMethod);
                        ((PropertyHelper <TAtt>)Setter).SetSet(setterDelegate);
                    }
                }
            }
            else
            {
                if (getMethod != null)
                {
                    Getter = new MethodInfoCache <TAtt, MethodArgsInfoCache <TAtt> >(getMethod);
                }
                if (setMethod != null)
                {
                    Setter = new MethodInfoCache <TAtt, MethodArgsInfoCache <TAtt> >(setMethod);
                }
            }

            Attributes = new HashSet <TAtt>(propertyInfo
                                            .GetCustomAttributes(true)
                                            .Where(s => s is Attribute)
                                            .Select(s => new TAtt().Init(s as Attribute) as TAtt));

            return(this);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Internal use Only
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="anon"></param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException">The object is already Initialed. A Change is not allowed</exception>
        public virtual IPropertyInfoCache <TAtt> Init(PropertyInfo propertyInfo, bool anon)
        {
            if (!string.IsNullOrEmpty(PropertyName))
            {
                throw new InvalidOperationException("The object is already Initialed. A Change is not allowed");
            }

            Attributes.Clear();
            if (propertyInfo == null)
            {
                return(this);
            }

            var getMethod = propertyInfo.GetMethod;
            var setMethod = propertyInfo.SetMethod;

            PropertyInfo = propertyInfo;
            PropertyName = propertyInfo.Name;
            PropertyType = propertyInfo.PropertyType;

            if (!anon && (getMethod != null || setMethod != null))
            {
                var isStatic = getMethod != null
                                        ? getMethod.Attributes.HasFlag(MethodAttributes.Static)
                                        : setMethod.Attributes.HasFlag(MethodAttributes.Static);

                //var builder = MetaInfoStoreExtentions.GetExpressionLambda();

                if (isStatic)
                {
                    GetterDelegate = typeof(Func <>).MakeGenericType(propertyInfo.PropertyType);
                    SetterDelegate = typeof(Action <>).MakeGenericType(propertyInfo.PropertyType);
                    var accessField = Expression.Property(null, propertyInfo);

                    if (getMethod != null)
                    {
                        var getterDelegate = Expression.Lambda(accessField);

                        //var getExpression = builder
                        //	.MakeGenericMethod(GetterDelegate)
                        //	.Invoke(null, new object[]
                        //	{
                        //		accessField, null
                        //	});

                        //var getterDelegate = MetaInfoStoreExtentions
                        //	.GetCompileMethodFromExpression(getExpression.GetType())
                        //	.Invoke(getExpression, null);

                        Getter = new PropertyHelper <TAtt>(getMethod);
                        ((PropertyHelper <TAtt>)Getter).SetGet(getterDelegate);
                    }

                    if (setMethod != null)
                    {
                        var valueRef = Expression.Parameter(propertyInfo.PropertyType, "newValue");
                        var setter   = Expression.Assign(
                            accessField,
                            valueRef);

                        var setterDelegate = Expression.Lambda(setter, valueRef);
                        //var setExpression = builder
                        //	.MakeGenericMethod(SetterDelegate)
                        //	.Invoke(null, new object[]
                        //	{
                        //		setter,
                        //		new[]
                        //		{
                        //			valueRef
                        //		}
                        //	});

                        //var setterDelegate = MetaInfoStoreExtentions
                        //	.GetCompileMethodFromExpression(setExpression.GetType())
                        //	.Invoke(setExpression, null);

                        Setter = new PropertyHelper <TAtt>(setMethod);
                        ((PropertyHelper <TAtt>)Setter).SetSet(setterDelegate);
                    }
                }
                else
                {
                    GetterDelegate =
                        typeof(Func <,>).MakeGenericType(propertyInfo.DeclaringType, propertyInfo.PropertyType);
                    SetterDelegate = typeof(Func <, ,>).MakeGenericType(propertyInfo.DeclaringType,
                                                                        propertyInfo.PropertyType,
                                                                        propertyInfo.DeclaringType);
                    var thisRef = Expression.Parameter(propertyInfo.DeclaringType, "that");

                    var accessField = Expression.MakeMemberAccess(thisRef, propertyInfo);

                    if (getMethod != null)
                    {
                        var getExpression = Expression.Lambda(accessField, thisRef);

                        //var getExpression = builder
                        //	.MakeGenericMethod(GetterDelegate)
                        //	.Invoke(null, new object[]
                        //	{
                        //		accessField,
                        //		new[] {thisRef}
                        //	}) as dynamic;

                        var getterDelegate = getExpression.Compile();
                        Getter = new PropertyHelper <TAtt>(getMethod);
                        ((PropertyHelper <TAtt>)Getter).SetGet(getterDelegate);
                    }

                    if (setMethod != null)
                    {
                        Setter = new PropertyHelper <TAtt>(setMethod);
                        try
                        {
                            var valueRef = Expression.Parameter(propertyInfo.PropertyType, "newValue");
                            var setter   = Expression.Assign(
                                accessField,
                                valueRef);
                            var makeRetunLabel = Expression.Label(propertyInfo.DeclaringType);
                            var retunLabel     = Expression.Label(makeRetunLabel,
                                                                  Expression.Default(propertyInfo.DeclaringType));
                            var returnMaybeValueType = Expression.Return(makeRetunLabel, thisRef);

                            var setExpression = Expression.Lambda(
                                Expression.Block(setter, returnMaybeValueType, retunLabel),
                                thisRef, valueRef);
                            //var setExpression = builder
                            //	.MakeGenericMethod(SetterDelegate)
                            //	.Invoke(null, new object[]
                            //	{
                            //		Expression.Block(setter, returnMaybeValueType, retunLabel),
                            //		new[] {thisRef, valueRef}
                            //	}) as dynamic;

                            var setterDelegate = setExpression.Compile();
                            ((PropertyHelper <TAtt>)Setter).SetSet(setterDelegate);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex);
                            //sometimes the Compile method does throw an error. In this case fall back to reflection
                            var setDelegate = setMethod.CreateDelegate(SetterDelegate);
                            ((PropertyHelper <TAtt>)Setter).SetSet(setDelegate);
                        }
                    }
                }
            }
            else
            {
                if (getMethod != null)
                {
                    Getter = new MethodInfoCache <TAtt, MethodArgsInfoCache <TAtt> >();
                    Getter.Init(getMethod);
                }

                if (setMethod != null)
                {
                    Setter = new MethodInfoCache <TAtt, MethodArgsInfoCache <TAtt> >();
                    Setter.Init(setMethod);
                }
            }

            Attributes = new HashSet <TAtt>(propertyInfo
                                            .GetCustomAttributes(true)
                                            .Where(s => s is Attribute)
                                            .Select(s => new TAtt().Init(s as Attribute) as TAtt));

            return(this);
        }