Ejemplo n.º 1
0
        public void CanGetSet_Prop_WhichIsReadAndWrite_CanBeReadAndWritten()
        {
            var prop = new PropertyFieldInfo <PropertyFieldClass, string>(p => p.PublicProperty);

            Assert.IsTrue(prop.CanGet);
            Assert.IsTrue(prop.CanSet);
        }
Ejemplo n.º 2
0
        public void New_WithImplicitCastRequired_CreatesPropertyFieldInfo()
        {
            Expression <Func <PropertyFieldClass, object> > expression = item => item.PublicField;

            Assert.DoesNotThrow(() =>
                                _ = new PropertyFieldInfo <PropertyFieldClass, object>(expression));
        }
Ejemplo n.º 3
0
        public void CanGetSet_Field_WhichIsReadOnly_CanBeReadAndNotWritten()
        {
            var field = new PropertyFieldInfo <PropertyFieldClass, DateTime>(p => p.PublicFieldReadOnly);

            Assert.IsTrue(field.CanGet);
            Assert.IsFalse(field.CanSet);
        }
Ejemplo n.º 4
0
        public void New_WithMethodMemberInfo_ThrowsArgumentException()
        {
            MemberInfo member = typeof(PropertyFieldClass).GetMember(nameof(PropertyFieldClass.ToString))[0];

            Assert.Throws <ArgumentException>(() =>
                                              _ = new PropertyFieldInfo <PropertyFieldClass, string>(member));
        }
Ejemplo n.º 5
0
        public void New_WithPropertyMemberInfo_ThrowsArgumentException()
        {
            MemberInfo member = typeof(PropertyFieldClass).GetProperty(nameof(PropertyFieldClass.PublicProperty));

            Assert.DoesNotThrow(() =>
                                _ = new PropertyFieldInfo <PropertyFieldClass, string>(member));
        }
Ejemplo n.º 6
0
        public void New_WithMethodAccessExpression_ThrowsArgumentException()
        {
            Expression <Func <PropertyFieldClass, string> > expression = item => item.ToString();

            Assert.Throws <ArgumentException>(() =>
                                              _ = new PropertyFieldInfo <PropertyFieldClass, string>(expression));
        }
Ejemplo n.º 7
0
        public void ToPropertyInfo_WhenProperty_Converts()
        {
            var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, string>(pf => pf.PublicProperty);

            var prop = (PropertyInfo)propFieldInfo;

            Assert.AreEqual(propFieldInfo.Member, prop);
        }
Ejemplo n.º 8
0
        public void GettingWhetherAutoProperty_WhenItIsAField_ReturnsFalse()
        {
            // Arrange
            var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, DateTime>(t => t.PublicField);

            // Assert
            Assert.IsFalse(propFieldInfo.IsAutoProperty);
        }
Ejemplo n.º 9
0
        public void ToMember_WhenProperty_Converts()
        {
            var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, string>(pf => pf.PublicProperty);

            var member = (MemberInfo)propFieldInfo;

            Assert.AreEqual(propFieldInfo.Member, member);
        }
Ejemplo n.º 10
0
        public void ToMember_WhenField_Converts()
        {
            var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, DateTime>(pf => pf.PublicField);

            var member = (MemberInfo)propFieldInfo;

            Assert.AreEqual(propFieldInfo.Member, member);
        }
Ejemplo n.º 11
0
        public void GettingAnAttribute_FromAMember_GetsTheAttribute()
        {
            MemberInfo prop = new PropertyFieldInfo <AttributesClass, string>(a => a.RandomAttributeTest).Member;

            DebuggerBrowsableAttribute attribute = prop.GetAttribute <DebuggerBrowsableAttribute>();

            Assert.AreEqual(AttributesClass.RandomAttributeTestBrowsableState, attribute.State);
        }
Ejemplo n.º 12
0
        public void GettingWhetherAutoProperty_WhenItIs_ReturnsTrue()
        {
            // Arrange
            var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, string>(t => t.PublicProperty);

            // Assert
            Assert.IsTrue(propFieldInfo.IsAutoProperty);
        }
Ejemplo n.º 13
0
        public void SetValue_Field_WhichIsWritable_Sets()
        {
            var expected = new DateTime(2000, 1, 1);
            var instance = new PropertyFieldClass();

            var field = new PropertyFieldInfo <PropertyFieldClass, DateTime>(p => p.PublicField);

            field.SetValue(instance, expected);

            Assert.AreEqual(expected, instance.PublicField);
        }
Ejemplo n.º 14
0
        public void GetValue_Field_WhichIsReadonly_Gets()
        {
            var expected = new DateTime(2000, 1, 1);
            var instance = new PropertyFieldClass(expected);

            var prop = new PropertyFieldInfo <PropertyFieldClass, DateTime>(p => p.PublicFieldReadOnly);

            DateTime result = prop.GetValue(instance);

            Assert.AreEqual(expected, result);
        }
Ejemplo n.º 15
0
        public void SetValue_Prop_WhichIsWritable_Sets()
        {
            var expected = "test";
            var instance = new PropertyFieldClass();

            var prop = new PropertyFieldInfo <PropertyFieldClass, string>(p => p.PublicProperty);

            prop.SetValue(instance, expected);

            Assert.AreEqual(expected, instance.PublicProperty);
        }
Ejemplo n.º 16
0
        public void GetValue_Prop_WhichIsReadonly_Gets()
        {
            var expected = "test";
            var instance = new PropertyFieldClass(expected);

            var prop = new PropertyFieldInfo <PropertyFieldClass, string>(p => p.PublicGetOnlyProperty);

            var result = prop.GetValue(instance);

            Assert.AreEqual(expected, result);
        }
Ejemplo n.º 17
0
        public void GetSetValue_ForValueWithImplicitCast_GetsAndSets()
        {
            object value    = new DateTime(2000, 1, 1);
            var    instance = new PropertyFieldClass();

            var field = new PropertyFieldInfo <PropertyFieldClass, object>(p => p.PublicField);

            field.SetValue(instance, value);

            Assert.AreEqual(value, instance.PublicField);
            Assert.AreEqual(value, field.GetValue(instance));
        }
Ejemplo n.º 18
0
        public void GettingAProperty_WhichIsPrivate_GetsTheCorrectName()
        {
            string propName = "PrivateProperty";

            var propInfo =
                typeof(PropertyFieldClass).GetProperty(propName,
                                                       BindingFlags.Instance | BindingFlags.NonPublic);

            var prop = new PropertyFieldInfo <PropertyFieldClass, int>(propInfo);

            Assert.AreEqual(propName, prop.Name);
        }
Ejemplo n.º 19
0
        public void GettingAField_WhichIsPrivate_GetsTheCorrectName()
        {
            string fieldName = "_privateField";

            var fieldInfo =
                typeof(PropertyFieldClass).GetField(fieldName,
                                                    BindingFlags.Instance | BindingFlags.NonPublic);

            var field = new PropertyFieldInfo <PropertyFieldClass, int>(fieldInfo);

            Assert.AreEqual(fieldName, field.Name);
        }
Ejemplo n.º 20
0
        public static string GetResourceId(object forObject)
        {
            if (forObject == null)
            {
                return(String.Empty);
            }

            object idValue = null;

            var type = forObject.GetType();
            var idPropertiesByAttribute = type.GetPropertiesAndFields(TypeExtensions.PUBLIC_INSTANCE)
                                          .Where(p => p.IsDefined(typeof(ResourceIdAttribute), true))
                                          .ToList();

            if (idPropertiesByAttribute.Count > 1)
            {
                throw new JsonApiSpecException("Resource objects may only have one [ResourceId] attribute");
            }
            if (idPropertiesByAttribute.Count == 1)
            {
                idValue = idPropertiesByAttribute.First().GetValue(forObject);
            }
            if (idPropertiesByAttribute.Count == 0)
            {
                PropertyFieldInfo idProperty = forObject.GetType().GetPropertyOrField("Id", TypeExtensions.PUBLIC_INSTANCE);
                if (idProperty != null)
                {
                    idValue = idProperty.GetValue(forObject);
                }
                else
                {
                    throw new JsonApiSpecException("Resource objects must have an Id field or a field marked with the [ResourceId] attribute");
                }
            }

            if (idValue == null || string.IsNullOrWhiteSpace(idValue.ToString()))
            {
                throw new JsonApiSpecException("Resource object Ids cannot be null or empty");
            }

            return(idValue.ToString());
        }
Ejemplo n.º 21
0
        public void GetType_WhenProperty_GetsType()
        {
            var propField = new PropertyFieldInfo <PropertyFieldClass, string>(pf => pf.PublicGetOnlyProperty);

            Assert.AreEqual(typeof(string), propField.Type);
        }
Ejemplo n.º 22
0
        public void GetType_WhenField_GetsType()
        {
            var propField = new PropertyFieldInfo <PropertyFieldClass, DateTime>(pf => pf.PublicFieldReadOnly);

            Assert.AreEqual(typeof(DateTime), propField.Type);
        }
Ejemplo n.º 23
0
        public void GettingAField_WhichIsPublic_GetsTheCorrectName()
        {
            var field = new PropertyFieldInfo <PropertyFieldClass, DateTime>(p => p.PublicField);

            Assert.AreEqual(nameof(PropertyFieldClass.PublicField), field.Name);
        }
Ejemplo n.º 24
0
        public void GettingAProperty_WhichIsPublic_GetsTheCorrectName()
        {
            var prop = new PropertyFieldInfo <PropertyFieldClass, string>(p => p.PublicProperty);

            Assert.AreEqual(nameof(PropertyFieldClass.PublicProperty), prop.Name);
        }
Ejemplo n.º 25
0
        public void New_WithNonMemberExpression_ThrowsArgumentException()
        {
            Expression <Func <PropertyFieldClass, string> > expression = item => null;

            Assert.Throws <ArgumentException>(() => _ = new PropertyFieldInfo <PropertyFieldClass, string>(expression));
        }
Ejemplo n.º 26
0
        public void ToFieldInfo_WhenProperty_ThrowsInvalidCastException()
        {
            var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, string>(pf => pf.PublicProperty);

            Assert.Throws <InvalidCastException>(() => _ = (FieldInfo)propFieldInfo);
        }
        /*
         * public class BaseType
         * {
         * public virtual string Name { get; set; }
         * }
         *
         * public class BaseType_<PropertyContainer>_Impl : BaseType, IPropertyContainer, IPropertyChangeNotifiable, INotifyPropertyChanged
         * {
         * private PropertyStore<BaseType_<PropertyContainer>_Impl> _store;
         * private IProperty<string> _name;
         *
         * public BaseType_<PropertyContainer>_Impl()
         * {
         *  _store = new PropertyStore<BaseType_<PropertyContainer>_Impl>(this);
         *  _name = _store.Create<String>("Name");
         * }
         *
         * public IPropertyStore PropertyStore => _store;
         *
         * public event PropertyChangedEventHandler PropertyChanged;
         *
         * public void NotifyPropertyChanged(PropertyChangedEventArgs args)
         * {
         *  PropertyChanged?.Invoke(this, args);
         * }
         *
         * public override string Name
         * {
         *  get => _name.Value;
         *  set => _name.Value = value;
         * }
         * }
         */

        private static Type CreateImplType(Type baseType)
        {
            var assemblyName = new AssemblyName {
                Name = "<PropertyContainer>_Assembly"
            };
            var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            var moduleBuilder   = assemblyBuilder.DefineDynamicModule("<PropertyContainer>_Module");
            var typeName        = GetImplTypeName(baseType);

            ////IPropertyContainerMarker = IPropertyContainer, IPropertyChangeNotifiable, INotifyPropertyChanged
            var interfaces  = new[] { typeof(IPropertyContainerMarker) };
            var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public, baseType, interfaces);

            ////Emit the PropertyChanged event and return its field so we can use it to implement the NotifyPropertyChanged method
            var eventFieldBuilder = EmitPropertyChangedField(typeBuilder);

            EmitNotifyPropertyChanged(typeBuilder, eventFieldBuilder);

            ////Emit the constructor and return the ILGenerator, it will be used to emit codes to create the IProperty<T>
            ////backing fields in the ctor
            var ctorIl = EmitCtor(typeBuilder, baseType);

            ////Emit the PropertyStore<T> field and corresponding property getter
            //// _store = new PropertyStore<BaseType_<PropertyContainer>_Impl>(this);
            var storeFieldBuilder = EmitPropertyStore(typeBuilder, ctorIl);

            ////This would be used to Emit codes like below to create backing fields for each property
            //// _name = _store.CreateImplicit<String>("Name");
            var createPropertyMethod = typeof(PropertyStore <>).GetMethod("CreateImplicit", BindingFlags.Instance | BindingFlags.Public);

            ////Prepare the properties need to be overridden and generate property getter and setter
            var targetProperties = GetTargetProperties(baseType);

            foreach (var property in targetProperties)
            {
                ////type of string
                var propertyType = property.PropertyType;
                var propertyName = property.Name;
                var fieldName    = ToFieldName(propertyName);
                ////type of IProperty<string>
                var fieldType    = typeof(IProperty <>).MakeGenericType(propertyType);
                var fieldBuilder = typeBuilder.DefineField(fieldName, fieldType, FieldAttributes.Private);

                var fieldInfo = new PropertyFieldInfo(propertyName, propertyType, fieldBuilder);

                var valueProperty  = fieldType.GetProperty("Value");
                var setValueMethod = valueProperty.GetSetMethod();
                var getValueMethod = valueProperty.GetGetMethod();

                ////private IProperty<string> _name;
                EmitPropertyBackingField(ctorIl, storeFieldBuilder, createPropertyMethod, fieldInfo);
                ////get => _name.Value;
                EmitPropertyGetter(typeBuilder, property, fieldBuilder, getValueMethod);
                ////set => _name.Value = value;
                EmitPropertySetter(typeBuilder, property, fieldBuilder, setValueMethod);
            }

            ctorIl.Emit(OpCodes.Ret);

            return(typeBuilder.CreateType());
        }
Ejemplo n.º 28
0
        public void ToPropertyInfo_WhenField_ThrowsInvalidCastException()
        {
            var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, DateTime>(pf => pf.PublicField);

            Assert.Throws <InvalidCastException>(() => _ = (PropertyInfo)propFieldInfo);
        }
Ejemplo n.º 29
0
        public void GettingADisplayName_WithoutDisplayAttribute_GetsMemberName()
        {
            MemberInfo prop = new PropertyFieldInfo <AttributesClass, string>(a => a.DisplayNameTest3).Member;

            Assert.AreEqual(AttributesClass.DisplayNameTest3Name, prop.GetDisplayName());
        }
        private static void EmitPropertyBackingField(ILGenerator ctorIl, FieldBuilder storeFieldBuilder, MethodInfo createPropertyMethod, PropertyFieldInfo fieldInfo)
        {
            var propertyName = fieldInfo.PropertyName;
            var fieldBuilder = fieldInfo.Builder;
            var propertyType = fieldInfo.PropertyType;
            var createMethod = TypeBuilder.GetMethod(storeFieldBuilder.FieldType, createPropertyMethod).MakeGenericMethod(propertyType);

            //IL_0011: ldarg.0
            ctorIl.Emit(OpCodes.Ldarg_0);                  ////Load this
            //IL_0012: ldarg.0
            ctorIl.Emit(OpCodes.Ldarg_0);                  ////Load this again
            //IL_0013: ldfld class PropertyStore`1<class C> C::_store
            ctorIl.Emit(OpCodes.Ldfld, storeFieldBuilder); ////Load this._propertyStore
            //IL_0018: ldstr "Name"
            ctorIl.Emit(OpCodes.Ldstr, propertyName);      ////Load "Name" as the name of the property

            ////Ideally we need to do type check and call corresponding OpCodes to load default value per type
            ////but in our case the 3rd parameter of the Property<> ctor is default(T) so OpCodes.Ldnull works fine

            // if (propertyType == typeof(string))
            // {
            //   ctorIl.Emit(OpCodes.Ldnull); ////Load default value of the property
            // }
            // else if (propertyType == typeof(int))
            // {
            //   ctorIl.Emit(OpCodes.Ldc_I4_0); ////Load default value of the property
            // }

            //IL_001d: ldnull
            ctorIl.Emit(OpCodes.Ldnull); ////Load default value of the property

            //IL_001e: callvirt instance class IProperty`1<!!0> class PropertyStore`1<class C>::Create<string>(string, !!0)
            ctorIl.Emit(OpCodes.Callvirt, createMethod); ////call _store.Create<String>("Name");
            //IL_0023: stfld class IProperty`1<string> C::_name
            ctorIl.Emit(OpCodes.Stfld, fieldBuilder);    ////_name = _store.Create<String>("Name");
        }