public override void CollectMembersToProxy( IProxyGenerationHook hook, IMembersCollectorSink sink ) { base.CollectMembersToProxy(hook, sink); CollectFields(hook); // TODO: perhaps we should also look for nested classes... }
public virtual void CollectMembersToProxy(IProxyGenerationHook hook, IMembersCollectorSink sink) { var checkedMethods = new HashSet <MethodInfo>(); CollectProperties(); CollectEvents(); // Methods go last, because properties and events have methods too (getters/setters add/remove) // and we don't want to get duplicates, so we collect property and event methods first // then we collect methods, and add only these that aren't there yet CollectMethods(); void CollectProperties() { var propertiesFound = type.GetProperties(Flags); foreach (var property in propertiesFound) { AddProperty(property); } } void CollectEvents() { var eventsFound = type.GetEvents(Flags); foreach (var @event in eventsFound) { AddEvent(@event); } } void CollectMethods() { var methodsFound = MethodFinder.GetAllInstanceMethods(type, Flags); foreach (var method in methodsFound) { AddMethod(method, true); } } void AddProperty(PropertyInfo property) { MetaMethod getter = null; MetaMethod setter = null; if (property.CanRead) { var getMethod = property.GetGetMethod(true); getter = AddMethod(getMethod, false); } if (property.CanWrite) { var setMethod = property.GetSetMethod(true); setter = AddMethod(setMethod, false); } if (setter == null && getter == null) { return; } var nonInheritableAttributes = property.GetNonInheritableAttributes(); var arguments = property.GetIndexParameters(); sink.Add(new MetaProperty(property, getter, setter, nonInheritableAttributes.Select(a => a.Builder), arguments.Select(a => a.ParameterType).ToArray())); } void AddEvent(EventInfo @event) { var addMethod = @event.GetAddMethod(true); var removeMethod = @event.GetRemoveMethod(true); MetaMethod adder = null; MetaMethod remover = null; if (addMethod != null) { adder = AddMethod(addMethod, false); } if (removeMethod != null) { remover = AddMethod(removeMethod, false); } if (adder == null && remover == null) { return; } sink.Add(new MetaEvent(@event, adder, remover, EventAttributes.None)); } MetaMethod AddMethod(MethodInfo method, bool isStandalone) { if (checkedMethods.Add(method) == false) { return(null); } var methodToGenerate = GetMethodToGenerate(method, hook, isStandalone); if (methodToGenerate != null) { sink.Add(methodToGenerate); } return(methodToGenerate); } }