public void CanGetSet_Prop_WhichIsReadAndWrite_CanBeReadAndWritten() { var prop = new PropertyFieldInfo <PropertyFieldClass, string>(p => p.PublicProperty); Assert.IsTrue(prop.CanGet); Assert.IsTrue(prop.CanSet); }
public void New_WithImplicitCastRequired_CreatesPropertyFieldInfo() { Expression <Func <PropertyFieldClass, object> > expression = item => item.PublicField; Assert.DoesNotThrow(() => _ = new PropertyFieldInfo <PropertyFieldClass, object>(expression)); }
public void CanGetSet_Field_WhichIsReadOnly_CanBeReadAndNotWritten() { var field = new PropertyFieldInfo <PropertyFieldClass, DateTime>(p => p.PublicFieldReadOnly); Assert.IsTrue(field.CanGet); Assert.IsFalse(field.CanSet); }
public void New_WithMethodMemberInfo_ThrowsArgumentException() { MemberInfo member = typeof(PropertyFieldClass).GetMember(nameof(PropertyFieldClass.ToString))[0]; Assert.Throws <ArgumentException>(() => _ = new PropertyFieldInfo <PropertyFieldClass, string>(member)); }
public void New_WithPropertyMemberInfo_ThrowsArgumentException() { MemberInfo member = typeof(PropertyFieldClass).GetProperty(nameof(PropertyFieldClass.PublicProperty)); Assert.DoesNotThrow(() => _ = new PropertyFieldInfo <PropertyFieldClass, string>(member)); }
public void New_WithMethodAccessExpression_ThrowsArgumentException() { Expression <Func <PropertyFieldClass, string> > expression = item => item.ToString(); Assert.Throws <ArgumentException>(() => _ = new PropertyFieldInfo <PropertyFieldClass, string>(expression)); }
public void ToPropertyInfo_WhenProperty_Converts() { var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, string>(pf => pf.PublicProperty); var prop = (PropertyInfo)propFieldInfo; Assert.AreEqual(propFieldInfo.Member, prop); }
public void GettingWhetherAutoProperty_WhenItIsAField_ReturnsFalse() { // Arrange var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, DateTime>(t => t.PublicField); // Assert Assert.IsFalse(propFieldInfo.IsAutoProperty); }
public void ToMember_WhenProperty_Converts() { var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, string>(pf => pf.PublicProperty); var member = (MemberInfo)propFieldInfo; Assert.AreEqual(propFieldInfo.Member, member); }
public void ToMember_WhenField_Converts() { var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, DateTime>(pf => pf.PublicField); var member = (MemberInfo)propFieldInfo; Assert.AreEqual(propFieldInfo.Member, member); }
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); }
public void GettingWhetherAutoProperty_WhenItIs_ReturnsTrue() { // Arrange var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, string>(t => t.PublicProperty); // Assert Assert.IsTrue(propFieldInfo.IsAutoProperty); }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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()); }
public void GetType_WhenProperty_GetsType() { var propField = new PropertyFieldInfo <PropertyFieldClass, string>(pf => pf.PublicGetOnlyProperty); Assert.AreEqual(typeof(string), propField.Type); }
public void GetType_WhenField_GetsType() { var propField = new PropertyFieldInfo <PropertyFieldClass, DateTime>(pf => pf.PublicFieldReadOnly); Assert.AreEqual(typeof(DateTime), propField.Type); }
public void GettingAField_WhichIsPublic_GetsTheCorrectName() { var field = new PropertyFieldInfo <PropertyFieldClass, DateTime>(p => p.PublicField); Assert.AreEqual(nameof(PropertyFieldClass.PublicField), field.Name); }
public void GettingAProperty_WhichIsPublic_GetsTheCorrectName() { var prop = new PropertyFieldInfo <PropertyFieldClass, string>(p => p.PublicProperty); Assert.AreEqual(nameof(PropertyFieldClass.PublicProperty), prop.Name); }
public void New_WithNonMemberExpression_ThrowsArgumentException() { Expression <Func <PropertyFieldClass, string> > expression = item => null; Assert.Throws <ArgumentException>(() => _ = new PropertyFieldInfo <PropertyFieldClass, string>(expression)); }
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()); }
public void ToPropertyInfo_WhenField_ThrowsInvalidCastException() { var propFieldInfo = new PropertyFieldInfo <PropertyFieldClass, DateTime>(pf => pf.PublicField); Assert.Throws <InvalidCastException>(() => _ = (PropertyInfo)propFieldInfo); }
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"); }