Esempio n. 1
0
        internal static Func <TParent, IEnumerable <TChild> > CreatePropertySetup <TParent, TChild>(this Type itemType, string propertyName)
        //where TParent : class
        //where TChild : class
        {
            var key = new PropertySetterKey(itemType, typeof(TChild), propertyName);

            var setter = _collectionInitialiserCache.GetOrAdd(key, k =>
            {
                var pi = itemType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);

                var tChildType  = pi.PropertyType;
                var parentParam = Expression.Parameter(itemType, "p");
                var property    = Expression.Property(parentParam, propertyName);

                var isParamNull = Expression.Equal(property, Expression.Constant(null));

                var collectionTypeToCreate = GetTypeToCreate(tChildType);
                if (collectionTypeToCreate.GetConstructor(Type.EmptyTypes) == null)
                {
                    throw new ArgumentException("Collection must have a parameterless constructor. Try instantiating " +
                                                "the item in the owners ctor");
                }

                Expression newCollection = null;
                if (collectionTypeToCreate.IsGenericTypeDefinition)
                {
                    newCollection = Expression.New(collectionTypeToCreate.MakeGenericType(new Type[] { typeof(TChild) }));
                }
                else
                {
                    newCollection = Expression.New(collectionTypeToCreate);
                }

                var mi  = pi.GetSetMethod();
                var mce = Expression.Call(parentParam, mi, newCollection);

                var @if = Expression.IfThen(isParamNull, mce);

                var expressions = new List <Expression>
                {
                    @if
                };

                var returnTarget = Expression.Label(typeof(IEnumerable <TChild>));
                expressions.Add(Expression.Return(returnTarget, property, typeof(IEnumerable <TChild>)));
                expressions.Add(Expression.Label(returnTarget, Expression.Constant(default(IEnumerable <TChild>), typeof(IEnumerable <TChild>))));

                var block = Expression.Block(expressions);



                var finalCode = Expression.Lambda <Func <TParent, IEnumerable <TChild> > >(block, parentParam);

                return(new CollectionInitializer <TParent, TChild>(finalCode.Compile()));
            });

            var typesSetter = setter as CollectionInitializer <TParent, TChild>;

            return(typesSetter?.Initializer);
        }
Esempio n. 2
0
        public static object GetPropertySetter(Type tObject, Type tProperty, string propertyName)
        {
            var key = new PropertySetterKey(tObject, propertyName);

            if (Setters.TryGetValue(key, out object propertySetter))
            {
                return(propertySetter);
            }

            return(ReflectionUtils
                   .GetMethod(() => GetPropertySetter <object, object>(""), tObject, tProperty)
                   .Invoke(null, new object[] { propertyName }));
        }
Esempio n. 3
0
        public static PropertySetter <TObject> GetPropertySetter <TObject, TProperty>(string propertyName)
        {
            var key = new PropertySetterKey(typeof(TObject), propertyName);

            if (Setters.TryGetValue(key, out object propertySetter))
            {
                return((PropertySetter <TObject>)propertySetter);
            }

            var propertySetter2 = BuildPropertySetter <TObject, TProperty>(propertyName);

            Setters.GetOrAdd(key, propertySetter2);
            return(propertySetter2);
        }
        internal static Action <TElement, TValue> CreatePropertySetter <TElement, TValue>(
            this Type elementType, string propertyName)
        {
            var key    = new PropertySetterKey(elementType, typeof(TValue), propertyName);
            var setter = _propertySetterCache.GetOrAdd(key, k =>
            {
                var pi = k.ElementType.GetProperty(k.PropertyName, BindingFlags.Public | BindingFlags.Instance);
                var mi = pi.GetSetMethod();

                var oParam = Expression.Parameter(k.ElementType, "obj");
                var vParam = Expression.Parameter(k.ValueType, "val");
                var mce    = Expression.Call(oParam, mi, vParam);
                var action = Expression.Lambda <Action <TElement, TValue> >(mce, oParam, vParam);

                return(new PropertySetterCache <TElement, TValue>(action.Compile()));
            });

            var typedSetter = setter as PropertySetterCache <TElement, TValue>;

            return(typedSetter?.Setter);
        }
        internal static Action <TElement, TValue> CreateCollectionPropertySetter <TElement, TValue>(
            this Type elementType, string propertyName, Type propertyType)
        {
            var key = new PropertySetterKey(elementType, typeof(TValue), propertyName);

            var setter = _collectionSetterCache.GetOrAdd(key, k =>
            {
                var oParam = Expression.Parameter(k.ElementType, "obj");
                var vParam = Expression.Parameter(k.ValueType, "val");
                var mce    = Expression.Call(
                    Expression.Convert(
                        Expression.Property(oParam, k.PropertyName)
                        , typeof(ICollection <TValue>))
                    , typeof(ICollection <TValue>).GetMethod("Add"), vParam);

                var action = Expression.Lambda <Action <TElement, TValue> >(mce, oParam, vParam);

                return(new PropertySetterCache <TElement, TValue>(action.Compile()));
            });

            var typedSetter = setter as PropertySetterCache <TElement, TValue>;

            return(typedSetter?.Setter);
        }