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()));
                    }
                }
            }
        }
Beispiel #3
0
        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()));
            }
        }
Beispiel #5
0
        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);
                }
            }
        }