private void HandleReceiveValueFromAttributes <TProperty>(string propertyName, TProperty oldValue, TProperty newValue, bool areDifferent) { var membersToNotify = new List <ReceiveValueFromArgs>(); var members = Enumerable.Empty <MemberInfo>() .Concat(GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) .Concat(GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) .Concat(GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)); // first collect members to notify foreach (var m in members) { foreach (var attrib in m.GetCustomAttributes(typeof(ReceiveValueFromAttribute), false) .Cast <ReceiveValueFromAttribute>()) { if ((attrib.SenderName ?? string.Empty).Trim() != propertyName) { // does not match continue; } if (!CheckNotifictionAttributeOptions(attrib, areDifferent)) { continue; } var args = new ReceiveValueFromArgs() { Attribute = attrib, NotifiableObject = this, NewValue = newValue, OldValue = oldValue, TargetMember = m, }; membersToNotify.Add(args); } } // now invoke them in a specific order foreach (var args in membersToNotify.OrderBy(x => x.Attribute.SortOrder) .ThenBy(x => x.TargetMember.Name, StringComparer.Ordinal)) { try { object resultToHandle = null; if (args.TargetMember is MethodInfo) { var method = (MethodInfo)args.TargetMember; object[] methodParams = null; var @params = method.GetParameters(); if (@params.Length > 0) { if (@params.Length > 2) { // submit sender name, old and new value methodParams = new object[] { args.SenderName, oldValue, newValue }; } else if (@params.Length > 1) { // submit old and new value methodParams = new object[] { oldValue, newValue }; } else { methodParams = new object[1]; methodParams[0] = args; if (!@params[0].ParameterType.Equals(typeof(IReceiveValueFromArgs))) { // submit new value instead methodParams[0] = newValue; } } } resultToHandle = method.Invoke(obj: this, parameters: methodParams); } else if (args.TargetMember is PropertyInfo) { var property = (PropertyInfo)args.TargetMember; if (property.Name == propertyName) { // not allowed continue; } object propertyValue = args.NewValue; if (property.PropertyType.Equals(typeof(IReceiveValueFromArgs))) { // use argument object instead propertyValue = args; } object[] index = null; var indexParams = property.GetIndexParameters(); if (indexParams.Length > 0) { if (indexParams.Length > 1) { // [Type][string] index = new object[] { typeof(TProperty), args.SenderName }; } else { index = new object[1]; if (indexParams[0].ParameterType.Equals(typeof(Type)) || typeof(Type).IsSubclassOf(indexParams[0].ParameterType) || typeof(Type).GetInterfaces().Any(x => x.Equals(indexParams[0].ParameterType))) { // property type index[0] = typeof(TProperty); } else { // sender name index[0] = args.SenderName; } } } property.SetValue(obj: this, value: propertyValue, index: index); resultToHandle = propertyValue; } else if (args.TargetMember is FieldInfo) { var field = (FieldInfo)args.TargetMember; var fieldValue = args.NewValue; if (field.FieldType.Equals(typeof(IReceiveValueFromArgs))) { // use argument object instead fieldValue = args; } field.SetValue(this, fieldValue); resultToHandle = fieldValue; } var resultHandler = args.ResultHandler; if (resultHandler != null) { resultHandler(args, resultToHandle); } } catch (Exception ex) { RaiseError(ex); } } }
private void HandleReceiveValueFromAttributes <T>(string propertyName, T oldValue, T newValue) { var members = Enumerable.Empty <_MemberInfo>() .Concat(this.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) .Concat(this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) .Concat(this.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)); foreach (var m in members) { foreach (var attrib in m.GetCustomAttributes(typeof(ReceiveValueFromAttribute), false) .Cast <ReceiveValueFromAttribute>()) { if ((attrib.SenderName ?? string.Empty).Trim() != propertyName) { // does not match continue; } var args = new ReceiveValueFromArgs(this) { NewValue = newValue, OldValue = oldValue, SenderName = propertyName, SenderType = MemberTypes.Property, }; if (m is _MethodInfo) { var method = (_MethodInfo)m; var @params = method.GetParameters(); if (@params.Length < 1) { method.Invoke(this, new object[] { }); } else if (@params.Length < 2) { method.Invoke(this, new object[] { args }); } } else if (m is _PropertyInfo) { var property = (_PropertyInfo)m; if (property.Name == propertyName) { // not allowed continue; } if (!property.CanWrite) { // no setter continue; } property.SetValue(this, args.NewValue, null); } else if (m is _FieldInfo) { var field = (_FieldInfo)m; field.SetValue(this, args.NewValue); } } } }