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); }
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)); }
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); }
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); }
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); }
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); });
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); } }
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); }
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())); } }
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; }
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); }
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); }
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)); }
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); } } } }
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; } } }
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); }
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); } } }
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; } } }