internal static void UpdateProperties(object target, Builtin builtin, IEnumerable <string> ignoredProperties) { if (target == null || builtin == null) { return; } foreach (string propertyName in builtin.Properties.Keys) { //如果当前属性名为忽略属性则忽略设置 if (ignoredProperties != null && ignoredProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase)) { continue; } try { Type propertyType; //如果构件中当前属性名在目标对象中不存在则记录告警日志 //注意:对于不存在的集合成员的获取类型可能会失败,但是下面的设置操作可能会成功,因此这里不能直接返回。 if (!Reflection.MemberAccess.TryGetMemberType(target, propertyName, out propertyType)) { Zongsoft.Diagnostics.Logger.Warn($"The '{propertyName}' property of '{builtin}' builtin is not existed on '{target.GetType().FullName}' target."); } //获取构件中当前属性的值 var propertyValue = builtin.Properties.GetValue(propertyName, propertyType, null); //将构件中当前属性值更新目标对象的对应属性中 Reflection.MemberAccess.TrySetMemberValue(target, propertyName, propertyValue); } catch (Exception ex) { var message = new StringBuilder(); message.AppendFormat("{0}[{1}]", ex.Message, ex.Source); message.AppendLine(); if (ex.InnerException != null) { message.AppendFormat("\t{0}: {1}[{2}]", ex.GetType().FullName, ex.Message, ex.Source); message.AppendLine(); } message.AppendFormat("\tOccurred an error on set '{1}' property of '{0}' builtin, it's raw value is \"{2}\", The target type of builtin is '{3}'.", builtin.ToString(), propertyName, builtin.Properties.GetRawValue(propertyName), target.GetType().AssemblyQualifiedName); throw new PluginException(message.ToString(), ex); } } }
private void ResolveBuiltinBehavior(XmlReader reader, Builtin builtin, string behaviorName) { var behavior = builtin.Behaviors.Add(behaviorName); for (int i = 0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); behavior.Properties.Set(reader.Name, reader.Value); } if (reader.NodeType == XmlNodeType.Attribute) { reader.MoveToElement(); } if (!reader.IsEmptyElement) { int depth = reader.Depth; if (reader.Read() && reader.Depth > depth) { if (reader.NodeType == XmlNodeType.Text) { behavior.Text = reader.Value; } else if (reader.NodeType == XmlNodeType.Element) { throw new PluginException(string.Format("This '{0}' builtin behavior element be contants child elements in '{1}'.", behaviorName, builtin.ToString())); } } } }
public static object BuildBuiltin(Builtin builtin, Builders.BuilderSettings settings, IEnumerable <string> ignoredProperties) { if (builtin == null) { throw new ArgumentNullException(nameof(builtin)); } object result = null; if (builtin.BuiltinType != null) { result = BuildType(builtin.BuiltinType); } else { //获取所有者元素的类型,如果所有者不是泛型集合则返回空 var type = GetOwnerElementType(builtin.Node) ?? settings?.TargetType; if (type == null) { throw new PluginException($"Unable to determine the target type of the '{builtin.ToString()}' builtin."); } result = BuildType(type, builtin); } //设置更新目标对象的属性集 if (result != null) { UpdateProperties(result, builtin, ignoredProperties); } return(result); }
private void ResolveExtendedElement(XmlReader reader, Builtin builtin) { if (builtin == null) { throw new ArgumentNullException("builtin"); } var parts = reader.Name.Split('.'); if (parts.Length != 2) { throw new PluginException(string.Format("Invalid '{0}' ExtendElement in '{1}'.", reader.Name, builtin.ToString())); } if (string.Equals(parts[0], builtin.BuilderName, StringComparison.OrdinalIgnoreCase)) { switch (parts[1].ToLowerInvariant()) { case "constructor": if (builtin.BuiltinType == null) { throw new PluginException(string.Format("This '{0}' ExtendElement dependencied builtin-type is null.", reader.Name)); } this.ResolveBuiltinConstructor(reader, builtin.BuiltinType.Constructor); break; default: this.ResolveBuiltinBehavior(reader, builtin, parts[1]); break; } } else if (string.Equals(parts[0], builtin.Name, StringComparison.OrdinalIgnoreCase)) { string propertyName = string.Join(".", parts, 1, parts.Length - 1); builtin.Properties.Set(propertyName, this.ResolveExtendedProperty(reader, builtin.Plugin, builtin.FullPath)); } else { throw new PluginException(string.Format("Invalid '{0}' ExtendElement in '{1}'.", reader.Name, builtin.ToString())); } }
internal static void UpdateProperties(object target, Builtin builtin, IEnumerable <string> ignoredProperties) { if (target == null || builtin == null || !builtin.HasProperties) { return; } foreach (var property in builtin.Properties) { //如果当前属性名为忽略属性则忽略设置 if (ignoredProperties != null && ignoredProperties.Contains(property.Name, StringComparer.OrdinalIgnoreCase)) { continue; } try { string converterTypeName = null; //Type propertyType; //如果构件中当前属性名在目标对象中不存在则记录告警日志 //注意:对于不存在的集合成员的获取类型可能会失败,但是下面的设置操作可能会成功,因此这里不能直接返回。 //if(!Reflection.MemberAccess.TryGetMemberType(target, property.Name, out propertyType, out converterTypeName)) // Zongsoft.Diagnostics.Logger.Warn($"The '{property.Name}' property of '{builtin}' builtin is not existed on '{target.GetType().FullName}' target."); //更新属性类型 //property.Type = propertyType; var propertyInfo = target.GetType().GetTypeInfo().DeclaredProperties.FirstOrDefault(p => p.CanRead && p.CanWrite && p.SetMethod.IsPublic && string.Equals(p.Name, property.Name, StringComparison.OrdinalIgnoreCase)); if (propertyInfo != null) { property.Type = propertyInfo.PropertyType; converterTypeName = propertyInfo.GetCustomAttribute <TypeConverterAttribute>()?.ConverterTypeName; } else { var fieldInfo = target.GetType().GetField(property.Name); if (fieldInfo != null) { property.Type = fieldInfo.FieldType; converterTypeName = fieldInfo.GetCustomAttribute <TypeConverterAttribute>()?.ConverterTypeName; } } //更新属性的类型转换器 if (converterTypeName != null && converterTypeName.Length > 0) { property.Converter = Activator.CreateInstance(GetType(converterTypeName)) as TypeConverter ?? throw new InvalidOperationException($"The '{converterTypeName}' type declared by the '{property.Name}' member of type '{target.GetType().FullName}' is not a type converter."); } //将构件中当前属性值更新目标对象的对应属性中 Reflector.TrySetValue(target, property.Name, property.Value); } catch (Exception ex) { if (System.Diagnostics.Debugger.IsAttached) { throw; } var message = new StringBuilder(); message.AppendFormat("{0}[{1}]", ex.Message, ex.Source); message.AppendLine(); if (ex.InnerException != null) { message.AppendFormat("\t{0}: {1}[{2}]", ex.GetType().FullName, ex.Message, ex.Source); message.AppendLine(); } message.AppendFormat("\tOccurred an error on set '{1}' property of '{0}' builtin, it's raw value is \"{2}\", The target type of builtin is '{3}'.", builtin.ToString(), property.Name, builtin.Properties.GetRawValue(property.Name), target.GetType().AssemblyQualifiedName); throw new PluginException(message.ToString(), ex); } } }