public BuiltinBehavior(Builtin builtin, string name, string text = null)
        {
            if (builtin == null)
            {
                throw new ArgumentNullException(nameof(builtin));
            }

            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            _builtin    = builtin;
            _name       = name.Trim();
            _text       = text;
            _properties = new PluginElementPropertyCollection(builtin);
        }
Пример #2
0
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }

            Builtin target = obj as Builtin;

            if (target == null)
            {
                return(false);
            }

            return(string.Equals(_builderName, target.BuilderName, StringComparison.OrdinalIgnoreCase) &&
                   string.Equals(this.FullPath, target.FullPath, StringComparison.OrdinalIgnoreCase));
        }
Пример #3
0
        public BuiltinType(Builtin builtin, string typeName)
        {
            if (builtin == null)
            {
                throw new ArgumentNullException("builtin");
            }

            if (string.IsNullOrWhiteSpace(typeName))
            {
                throw new ArgumentNullException("typeName");
            }

            _type        = null;
            _builtin     = builtin;
            _typeName    = typeName.Trim();
            _constructor = new BuiltinTypeConstructor(this);
        }
Пример #4
0
        public static object BuildBuiltin(Builtin builtin, IEnumerable <string> ignoredProperties = null)
        {
            if (builtin == null)
            {
                throw new ArgumentNullException("builtin");
            }

            var result = PluginUtility.BuildType(builtin);

            //设置更新目标对象的属性集
            if (result != null)
            {
                UpdateProperties(result, builtin, ignoredProperties);
            }

            return(result);
        }
Пример #5
0
        private Builtin ResolveBuiltin(XmlReader reader, Builtin parent)
        {
            if (reader == null || reader.NodeType != XmlNodeType.Element)
            {
                return(null);
            }

            Builtin builtin = parent.Plugin.CreateBuiltin(reader.Name, reader.GetAttribute("name"));

            //设置当前构件的其他属性并将构件对象挂载到插件树中,该方法不会引起读取器的位置或状态变化。
            this.UpdateBuiltin(parent.FullPath, builtin, reader);

            //解析当前构件的内部元素(包括下属的子构件或扩展元素)
            this.ResolveBuiltinContent(reader, builtin);

            return(builtin);
        }
Пример #6
0
        internal static void UpdateProperties(object target, Builtin builtin, IEnumerable <string> ignoredProperties)
        {
            if (target == null || builtin == null)
            {
                return;
            }

            foreach (var property in builtin.GetProperties())
            {
                //如果当前属性名为忽略属性则忽略设置
                if (ignoredProperties != null && ignoredProperties.Contains(property.Name, StringComparer.OrdinalIgnoreCase))
                {
                    continue;
                }

                try
                {
                    var memberExpression = MemberExpression.Parse(property.Name);

                    MemberExpressionEvaluator.Default.SetValue(memberExpression, target, ctx =>
                    {
                        //更新扩展属性的类型
                        if (property.Type == null)
                        {
                            property.Type = ctx.Member switch
                            {
                                PropertyInfo propertyInfo => propertyInfo.PropertyType,
                                FieldInfo fieldInfo => fieldInfo.FieldType,
                                MethodInfo methodInfo => methodInfo.ReturnType,
                                _ => null,
                            };
                        }

                        var converterTypeName = ctx.Member.GetCustomAttribute <TypeConverterAttribute>(true)?.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.");
                        }

                        return(property.Value);
                    });
Пример #7
0
        private void UnmountItem(Plugin plugin, PluginTreeNode node)
        {
            if (node == null)
            {
                return;
            }

            if (plugin != null)
            {
                foreach (PluginTreeNode child in node.Children)
                {
                    this.UnmountItem(plugin, child);
                }
            }

            if (node.NodeType == PluginTreeNodeType.Custom)
            {
                this.Unmount(node);
                return;
            }

            if (node.NodeType == PluginTreeNodeType.Builtin)
            {
                Builtin builtin = (Builtin)node.Value;

                if (string.ReferenceEquals(builtin.Plugin, plugin))
                {
                    IBuilder builder = node.Plugin.GetBuilder(builtin.BuilderName);
                    if (builder != null)
                    {
                        builder.Destroy(Builders.BuilderContext.CreateContext(builder, builtin, this));
                    }

                    plugin.UnregisterBuiltin(builtin);
                    node.Value = null;
                }
            }

            if (node.Children.Count < 1 && node.Parent != null)
            {
                node.Parent.Children.Remove(node);
            }
        }
Пример #8
0
        private void UpdateBuiltin(string path, Builtin builtin, XmlReader reader)
        {
            //循环读取当前构件元素的所有特性,并设置到构件对象的扩展属性集合中
            for (int i = 0; i < reader.AttributeCount; i++)
            {
                reader.MoveToAttribute(i);

                switch (reader.Name.ToLowerInvariant())
                {
                case "name":
                    continue;

                case "position":
                    builtin.Position = reader.Value;
                    break;

                case "type":
                    if (builtin.BuiltinType == null)
                    {
                        builtin.BuiltinType = new BuiltinType(builtin, reader.Value);
                    }
                    else
                    {
                        builtin.BuiltinType.TypeName = reader.Value;
                    }
                    break;

                default:
                    builtin.Properties.Set(reader.Name, reader.Value);
                    break;
                }
            }

            //将当前读取器的位置重新移回该元素节点上
            if (reader.NodeType == XmlNodeType.Attribute)
            {
                reader.MoveToElement();
            }

            //在插件树中挂载当前构件对象
            this.PluginTree.MountBuiltin(path, builtin);
        }
Пример #9
0
        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()));
            }
        }
Пример #10
0
        private void SetBuiltin(Builtin builtin)
        {
            if (builtin == null)
            {
                throw new ArgumentNullException("builtin");
            }

            if (builtin.Node != null)
            {
                throw new InvalidOperationException();
            }

            //将构建的所属节点指向本节点
            builtin.Node = this;

            //更新当前节点的属性值
            _value      = builtin;
            _nodeType   = PluginTreeNodeType.Builtin;
            this.Plugin = builtin.Plugin;
        }
Пример #11
0
        internal static Zongsoft.Services.IServiceProvider FindServiceProvider(Builtin builtin)
        {
            if (builtin == null)
            {
                return(null);
            }

            var module = FindApplicationModule(builtin);

            if (module != null && module.Services != null)
            {
                return(module.Services);
            }

            if (builtin.Node != null && builtin.Node.Parent != null)
            {
                return(Services.ServiceProviderFactory.Instance.GetProvider(builtin.Node.Parent.Name) ?? builtin.Context.ApplicationContext.Services);
            }

            return(builtin.Context.ApplicationContext.Services);
        }
Пример #12
0
        internal static IServiceProvider FindServiceProvider(Builtin builtin)
        {
            if (builtin == null)
            {
                return(null);
            }

            var module = FindApplicationModule(builtin);

            if (module != null && module.Services != null)
            {
                return(module.Services);
            }

            if (builtin.Node != null && builtin.Node.Parent != null &&
                ApplicationContext.Current.Modules.TryGet(builtin.Node.Parent.Name, out module))
            {
                return(module.Services);
            }

            return(ApplicationContext.Current.Services);
        }
Пример #13
0
        internal void MountBuiltin(string path, Builtin builtin)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentNullException("path");
            }

            if (builtin == null)
            {
                throw new ArgumentNullException("builtin");
            }

            var fullPath = PluginPath.Combine(path, builtin.Name);

            //激发“Mounting”事件
            this.OnMounting(new PluginMountEventArgs(fullPath, builtin));

            //创建对应的构件节点
            this.MountItem(fullPath, builtin, builtin.Position);

            //激发“Mounted”事件
            this.OnMounted(new PluginMountEventArgs(fullPath, builtin));
        }
Пример #14
0
        private void ResolveBuiltinContent(XmlReader reader, Builtin builtin)
        {
            if (reader.IsEmptyElement)
            {
                return;
            }

            int depth = reader.Depth;

            while (reader.Read() && reader.Depth > depth)
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (this.IsExtendElement(reader.Name))
                    {
                        this.ResolveExtendedElement(reader, builtin);
                    }
                    else
                    {
                        this.ResolveBuiltin(reader, builtin);
                    }
                }
            }
        }
Пример #15
0
        private static void InjectProperties(object target, Builtin builtin)
        {
            if (target == null || builtin == null)
            {
                return;
            }

            //查找指定目标对象需要注入的属性和字段集(支持对非公共成员的注入)
            var members = target.GetType().FindMembers(MemberTypes.Field | MemberTypes.Property, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, (m, t) => m.GetCustomAttribute((Type)t, true) != null, typeof(Zongsoft.Services.ServiceDependencyAttribute));

            if (members == null || members.Length < 1)
            {
                return;
            }

            //定义成员值变量
            object memberValue;

            //获取当前构件所属的服务容器(后备服务容器)
            var reserveProvider = FindServiceProvider(builtin);

            //定义成员对应的服务容器(默认为后备服务容器)
            var serviceProvider = reserveProvider;

            foreach (var member in members)
            {
                //如果当前成员已经在构件属性集中显式存在则跳过
                if (builtin.HasProperties && builtin.Properties.Contains(member.Name))
                {
                    continue;
                }

                //获取需注入成员的注入标记
                var attribute = (Zongsoft.Services.ServiceDependencyAttribute)member.GetCustomAttribute(typeof(Zongsoft.Services.ServiceDependencyAttribute), true);

                if (attribute == null || string.IsNullOrWhiteSpace(attribute.Provider))
                {
                    serviceProvider = reserveProvider;
                }
                else
                {
                    serviceProvider = builtin.Context.ServiceFactory.GetProvider(attribute.Provider) ?? reserveProvider;
                }

                switch (member.MemberType)
                {
                case MemberTypes.Field:
                    if (!string.IsNullOrWhiteSpace(attribute.Name))
                    {
                        memberValue = serviceProvider.Resolve(attribute.Name);
                    }
                    else
                    {
                        memberValue = serviceProvider.Resolve(attribute.Contract ?? ((FieldInfo)member).FieldType);
                    }

                    ((FieldInfo)member).SetValue(target, memberValue);
                    break;

                case MemberTypes.Property:
                    if (((PropertyInfo)member).CanWrite)
                    {
                        if (!string.IsNullOrWhiteSpace(attribute.Name))
                        {
                            memberValue = serviceProvider.Resolve(attribute.Name);
                        }
                        else
                        {
                            memberValue = serviceProvider.Resolve(attribute.Contract ?? ((PropertyInfo)member).PropertyType);
                        }

                        ((PropertyInfo)member).SetValue(target, memberValue);
                    }

                    break;
                }
            }
        }
Пример #16
0
        internal static object BuildType(Type type, Builtin builtin)
        {
            object target;

            try
            {
                target = BuildType(type, (Type parameterType, string parameterName, out object parameterValue) =>
                {
                    if (parameterType == typeof(Builtin))
                    {
                        parameterValue = builtin;
                        return(true);
                    }

                    if (parameterType == typeof(PluginTreeNode))
                    {
                        parameterValue = builtin.Node;
                        return(true);
                    }

                    if (parameterType == typeof(string) && string.Equals(parameterName, "name", StringComparison.OrdinalIgnoreCase))
                    {
                        parameterValue = builtin.Name;
                        return(true);
                    }

                    if (typeof(IServiceProvider).IsAssignableFrom(parameterType))
                    {
                        parameterValue = FindServiceProvider(builtin);
                        return(true);
                    }

                    if (typeof(IApplicationContext).IsAssignableFrom(parameterType))
                    {
                        parameterValue = ApplicationContext.Current;
                        return(true);
                    }

                    if (typeof(IApplicationModule).IsAssignableFrom(parameterType))
                    {
                        parameterValue = FindApplicationModule(builtin);
                        return(true);
                    }

                    if (ObtainParameter(builtin.Plugin, parameterType, parameterName, out parameterValue))
                    {
                        return(true);
                    }

                    var services = FindServiceProvider(builtin);

                    if (services != null)
                    {
                        parameterValue = services.GetService(parameterType);
                        return(parameterValue != null);
                    }

                    return(false);
                });

                if (target == null)
                {
                    throw new PluginException(string.Format("Can not build instance of '{0}' type, Maybe that's cause type-generator not found matched constructor with parameters. in '{1}' builtin.", type.FullName, builtin));
                }
            }
            catch (Exception ex)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    throw;
                }

                throw new PluginException(string.Format("Occurred an exception on create a builtin instance of '{0}' type, at '{1}' builtin.", type.FullName, builtin), ex);
            }

            //注入依赖属性
            InjectProperties(target, builtin);

            return(target);
        }
Пример #17
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);
                }
            }
        }
Пример #18
0
        private static void InjectProperties(object target, Builtin builtin)
        {
            if (target == null || builtin == null)
            {
                return;
            }

            //查找指定目标对象需要注入的属性和字段集(支持对非公共成员的注入)
            var members = target.GetType()
                          .FindMembers(MemberTypes.Field | MemberTypes.Property,
                                       BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                                       (m, t) => m.GetCustomAttribute((Type)t, true) != null,
                                       typeof(Zongsoft.Services.ServiceDependencyAttribute));

            if (members == null || members.Length < 1)
            {
                return;
            }

            //定义成员值变量
            object memberValue;

            //获取当前构件所属的服务容器(后备服务容器)
            var reservedProvider = FindServiceProvider(builtin);

            //定义成员对应的服务容器(默认为后备服务容器)
            var serviceProvider = reservedProvider;

            foreach (var member in members)
            {
                //如果当前成员已经在构件属性集中显式存在则跳过
                if (builtin.HasProperties && builtin.Properties.Contains(member.Name))
                {
                    continue;
                }

                //获取需注入成员的注入标记
                var attribute = member.GetCustomAttribute <ServiceDependencyAttribute>(true);

                if (attribute == null || string.IsNullOrWhiteSpace(attribute.Provider))
                {
                    serviceProvider = reservedProvider;
                }
                else
                {
                    if (ApplicationContext.Current.Modules.TryGet(attribute.Provider, out var module))
                    {
                        serviceProvider = module.Services;
                    }
                    else
                    {
                        serviceProvider = reservedProvider;
                    }
                }

                switch (member.MemberType)
                {
                case MemberTypes.Field:
                    memberValue = serviceProvider.GetService(attribute.ServiceType ?? ((FieldInfo)member).FieldType);

                    if (memberValue == null && attribute != null && attribute.IsRequired)
                    {
                        throw new InvalidOperationException($"The injected {((PropertyInfo)member).Name} field value is null when building the '{builtin}' plugin builtin.");
                    }

                    ((FieldInfo)member).SetValue(target, memberValue);
                    break;

                case MemberTypes.Property:
                    if (((PropertyInfo)member).CanWrite)
                    {
                        memberValue = serviceProvider.GetService(attribute.ServiceType ?? ((PropertyInfo)member).PropertyType);

                        if (memberValue == null && attribute != null && attribute.IsRequired)
                        {
                            throw new InvalidOperationException($"The injected {((PropertyInfo)member).Name} property value is null when building the '{builtin}' plugin builtin.");
                        }

                        ((PropertyInfo)member).SetValue(target, memberValue);
                    }

                    break;
                }
            }
        }