Created
February 22, 2021 12:57
-
-
Save juanfranblanco/b7485fc2e8c9661aea576f13e8fea2d4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PropertyOverridingTypeDescriptor : CustomTypeDescriptor | |
{ | |
private readonly Dictionary<string, PropertyDescriptor> overridePds = new Dictionary<string, PropertyDescriptor>(); | |
public PropertyOverridingTypeDescriptor(ICustomTypeDescriptor parent) | |
: base(parent) | |
{ } | |
public void OverrideProperty(PropertyDescriptor pd) | |
{ | |
overridePds[pd.Name] = pd; | |
} | |
public override object GetPropertyOwner(PropertyDescriptor pd) | |
{ | |
object o = base.GetPropertyOwner(pd); | |
if (o == null) | |
{ | |
return this; | |
} | |
return o; | |
} | |
public PropertyDescriptorCollection GetPropertiesImpl(PropertyDescriptorCollection pdc) | |
{ | |
List<PropertyDescriptor> pdl = new List<PropertyDescriptor>(pdc.Count + 1); | |
foreach (PropertyDescriptor pd in pdc) | |
{ | |
if (overridePds.ContainsKey(pd.Name)) | |
{ | |
pdl.Add(overridePds[pd.Name]); | |
} | |
else | |
{ | |
pdl.Add(pd); | |
} | |
} | |
PropertyDescriptorCollection ret = new PropertyDescriptorCollection(pdl.ToArray()); | |
return ret; | |
} | |
public override PropertyDescriptorCollection GetProperties() | |
{ | |
return GetPropertiesImpl(base.GetProperties()); | |
} | |
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) | |
{ | |
return GetPropertiesImpl(base.GetProperties(attributes)); | |
} | |
} | |
public class TypeDescriptorOverridingProvider : TypeDescriptionProvider | |
{ | |
private readonly ICustomTypeDescriptor ctd; | |
public TypeDescriptorOverridingProvider(ICustomTypeDescriptor ctd) | |
{ | |
this.ctd = ctd; | |
} | |
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) | |
{ | |
return ctd; | |
} | |
} | |
private static void AddExtendedData() | |
{ | |
AddExtendedData<Service>(); | |
AddExtendedData<Context>(); | |
var properties = DeepCloner.GetFastDeepClonerProperties(typeof(Context)); | |
foreach (var property in properties) | |
{ | |
if (property.Name.StartsWith("AdditionalData")) | |
{ | |
property.Attributes.Add(new JsonExtensionDataAttribute()); | |
// // now test and se if exist | |
// prop = DeepCloner.GetFastDeepClonerProperties(typeof(test)).First(); | |
// bool containAttr = prop.ContainAttribute<JsonIgnoreAttribute>() | |
//// or | |
// JsonIgnoreAttribute myAttr = prop.GetCustomAttribute<JsonIgnoreAttribute>(); | |
} | |
} | |
} | |
private static void AddExtendedData<T>() | |
{ | |
var type = typeof(T); | |
PropertyOverridingTypeDescriptor ctd = new PropertyOverridingTypeDescriptor(TypeDescriptor.GetProvider(type).GetTypeDescriptor(type)); | |
// iterate through properies in the supplied object/type | |
foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(type)) | |
{ | |
// for every property that complies to our criteria | |
if (pd.Name.EndsWith("AdditionalData")) | |
{ | |
// we first construct the custom PropertyDescriptor with the TypeDescriptor's | |
// built-in capabilities | |
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. | |
new JsonExtensionDataAttribute() | |
// 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 instead of default | |
TypeDescriptor.AddProvider(new TypeDescriptorOverridingProvider(ctd), type); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment