//Property overriding taken from //http://stackoverflow.com/questions/12143650/how-to-add-property-level-attribute-to-the-typedescriptor-at-runtime private void OverrideProperty(Type type, string PropertyName, params Attribute[] attributes) { //Override the KeyValue type descriptors // prepare our property overriding type descriptor PropertyOverridingTypeDescriptor ctd = new PropertyOverridingTypeDescriptor(TypeDescriptor.GetProvider(type).GetTypeDescriptor(type)); // iterate through properies in the supplied object/type foreach (System.ComponentModel.PropertyDescriptor pd in TypeDescriptor.GetProperties(typeof(KeyValue))) { // for every property that complies to our criteria if (pd.Name == PropertyName) { // we first construct the custom PropertyDescriptor with the TypeDescriptor's // built-in capabilities System.ComponentModel.PropertyDescriptor pd2 = TypeDescriptor.CreateProperty( type, // or just _settings, if it's already a type pd, // base property descriptor to which we want to add attributes // The PropertyDescriptor which we'll get will just wrap that // base one returning attributes we need. attributes // this method really can take as many attributes as you like, // not just one ); // and then we tell our new PropertyOverridingTypeDescriptor to override that property ctd.OverrideProperty(pd2); } } // then we add new descriptor provider that will return our descriptor istead of default TypeDescriptor.AddProvider(new TypeDescriptorOverridingProvider(ctd), type); }
public void WhenOnlyTheNamePropertyIsSetInDto_GivenEntityWithMultiplePropertiesSetIncludingTheName_ShouldReturnEntityWithOnlyTheNameChanged() { var entity = new Category() { Name = "entity name", Description = "some description" }; var dto = new CategoryDto() { Name = "updated name" }; //Attributes are readonly - http://stackoverflow.com/questions/10046601/change-custom-attributes-parameter-at-runtime // So we are going to try to replace the attribute with new instance. //****************************** PropertyOverridingTypeDescriptor ctd = new PropertyOverridingTypeDescriptor(TypeDescriptor.GetProvider(dto).GetTypeDescriptor(dto)); PropertyDescriptor desriptionPorpertyDescriptor = ctd.GetProperties().Find("Description", true); PropertyDescriptor pd2 = TypeDescriptor.CreateProperty( dto.GetType(), desriptionPorpertyDescriptor, // base property descriptor to which we want to add attributes // The PropertyDescriptor which we'll get will just wrap that // base one returning attributes we need. new Updated(false) // this method really can take as many attributes as you like, // not just one ); // and then we tell our new PropertyOverridingTypeDescriptor to override that property ctd.OverrideProperty(pd2); // then we add new descriptor provider that will return our descriptor istead of default TypeDescriptor.AddProvider(new TypeDescriptorOverridingProvider(ctd), dto); //****************************** Category resultEntity = entity.Merge(dto); // The name should be updated Assert.AreEqual(dto.Name, resultEntity.Name); // The description shouldn't be updated Assert.NotNull(entity.Description); Assert.AreEqual(entity.Description, resultEntity.Description); }
public static void SetAttribute(string propName, params Attribute[] attr) { var _settings = Settings.Default; PropertyOverridingTypeDescriptor ctd = new PropertyOverridingTypeDescriptor(TypeDescriptor.GetProvider(_settings).GetTypeDescriptor(_settings)); foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(_settings)) { if (pd.Name == propName) { PropertyDescriptor pd2 = TypeDescriptor.CreateProperty(_settings.GetType(), pd, attr); ctd.OverrideProperty(pd2); } } TypeDescriptor.AddProvider(new TypeDescriptorOverridingProvider(ctd), _settings); }