Skip to content

Instantly share code, notes, and snippets.

@einarwh
Created April 28, 2012 21:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save einarwh/2522171 to your computer and use it in GitHub Desktop.
Save einarwh/2522171 to your computer and use it in GitHub Desktop.
Find properties to tamper with, including dependent properties.
private void HandlePropertyToNotify(PropertyDefinition prop)
{
foreach (var affector in FindAffectingProperties(prop, new List<string>()))
{
AddDependency(affector, prop);
}
}
private void AddDependency(PropertyDefinition key,
PropertyDefinition value)
{
if (!_map.ContainsKey(key))
{
_map[key] = new List<PropertyDefinition>();
}
_map[key].Add(value);
}
private List<PropertyDefinition> FindAffectingProperties(
PropertyDefinition prop,
IList<string> seen)
{
if (seen.Any(n => n == prop.Name))
{
return new List<PropertyDefinition>();
}
seen.Add(prop.Name);
if (prop.SetMethod != null)
{
return new List<PropertyDefinition> {prop};
}
if (prop.GetMethod != null)
{
return FindAffectingPropertiesFromGetter(prop.GetMethod, seen);
}
return new List<PropertyDefinition>();
}
private List<PropertyDefinition> FindAffectingPropertiesFromGetter(
MethodDefinition getter,
IList<string> seen)
{
var result = new List<PropertyDefinition>();
foreach (var insn in getter.Body.Instructions)
{
if (insn.OpCode == OpCodes.Call)
{
var methodRef = (MethodReference)insn.Operand;
if (methodRef.Name.StartsWith(PropertyGetterPrefix))
{
// Found an affecting getter inside the current getter!
// Get list of dependencies from this getter.
string affectingPropName = methodRef.Name
.Substring(PropertyGetterPrefix.Length);
var affectingProp = _typeDef.Properties
.FirstOrDefault(p => p.Name == affectingPropName);
if (affectingProp != null)
{
result.AddRange(FindAffectingProperties(affectingProp, seen));
}
}
}
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment