internal bool Introspect(IMessageDialog dialog) { var result = true; if (AddinHeader == null) { dialog.AddError(""); result = false; } else { result &= AddinHeader.Introspect(dialog); } if (ExtensionDeclaration == null && ExtensionImplementation == null) { dialog.AddError(""); result = false; } if (ExtensionDeclaration != null) { result &= ExtensionDeclaration.Introspect(dialog); } if (ExtensionImplementation != null) { result &= ExtensionImplementation.Introspect(dialog); } return(result); }
// apply some rules to extension point. protected bool ApplyRules(IMessageDialog dialog, ResolutionContext ctx, out TypeResolution extensionType) { var result = true; if (!Type.IsClass || Type.IsAbstract) { dialog.AddError(string.Format("The specified extension point type [{0}] is not a concrete class!", Type.TypeName)); result = false; } //if (!this.DeclaresInSameAddin()) //{ // dialog.AddError(string.Format("The extension point type [{0}] is expected to be defined and declared in a same addin, while its defining addin is [{1}], and its declaring addin is [{2}], which is not the same as the former!", Type.TypeName, Type.Assembly.DeclaringAddin.AddinId.Guid, DeclaringAddin.AddinId.Guid)); // result = false; //} if (!this.InheritFromExtensionPointInterface(dialog, ctx, out extensionType)) { dialog.AddError(string.Format("The specified extension point type [{0}] does not implement the required interface (IExtensionPoint<TExtension, TRoot>)!", Type.TypeName)); result = false; } if (!this.HasPublicParameterLessConstructor()) { dialog.AddError(string.Format("The specified extension point type [{0}] do not have a public parameter-less constructor!", Type.TypeName)); result = false; } return(result); }
static bool ExtensionBuilderMatchesParent(ExtensionResolution ex, IMessageDialog dialog) { var extensionBuilder = ex.ExtensionBuilder; var extensionPoint = ex.Parent as ExtensionPointResolution; bool result; if (extensionPoint != null) { result = extensionPoint.Children != null && extensionPoint.Children.Contains(extensionBuilder); if (!result) { dialog.AddError(string.Format("The extension builder of the extension [{0}] is not a child of that of the extension point [{1}]!", ex.Head.Path, extensionPoint.Id)); } return(result); } var parentObj = ex.Parent as ExtensionResolution; // the child extension builders of the extension builder for parent extension. result = parentObj.ExtensionBuilder.Children.Contains(extensionBuilder); if (!result) { dialog.AddError(string.Format("The extension builder of the extension [{0}] is not a child of that of its parent [{1}]!", ex.Head.Path, parentObj.Head.Path)); } return(result); }
internal bool Introspect(IMessageDialog dialog) { if (ParentPath == null) { dialog.AddError(""); return(false); } if (_children == null) { dialog.AddError(""); return(false); } return(true); }
// The resolution of an extension point depends on the existence of its implementation type (IExtensionPoint<TExtension, TRoot>), // extension type (TExtension) and root type (TRoot), and it needs to obey some rules. internal override ResolutionStatus Resolve(IMessageDialog dialog, ConvertionManager convertionManager, ResolutionContext ctx) { if (Type == null) { Type = ctx.GetUniqueAddinType(DeclaringAddin, TypeName); if (Type == null) { dialog.AddError(string.Format("Can not find the specified extension point type [{0}]!", TypeName)); return(ResolutionStatus.Failed); } TypeResolution extensionType; if (!ApplyRules(dialog, ctx, out extensionType)) { return(ResolutionStatus.Failed); } ExtensionType = extensionType; if (Type.Assembly.DeclaringAddin != null && !ReferenceEquals(Type.Assembly.DeclaringAddin, DeclaringAddin)) { AssemblyResolutionSet assemblySet; if (!ctx.TryGetAssemblySet(Type.Assembly.AssemblyKey, out assemblySet)) { throw new Exception(); } DeclaringAddin.AddReferencedAssemblySet(assemblySet); } } return(ResolveType(Type)); }
internal override bool Introspect(IMessageDialog dialog) { var result = true; if (ExtensionPointId == null) { dialog.AddError("An id of extension point must have an parent!"); result = false; } if (ParentPath == null) { dialog.AddError("An extension builder must have an parent!"); result = false; } return(result | DoIntrospect(dialog, "extension builder")); }
// get assembly references of @assembly that requires resolution at the runtime, which is not provided runtime or application itself. public bool TryGetRequiredAssemblyReferences(IMessageDialog dialog, AssemblyResolution assembly, out List <AssemblyResolutionSet> result) { var assemblyKeys = assembly.GetRequiredAssemblyReferences(); if (assemblyKeys == null) // all referenced assemblies are provided by runtime or application itself. { result = null; return(true); } result = new List <AssemblyResolutionSet>(assemblyKeys.Count); for (int i = 0; i < assemblyKeys.Count; i++) { AssemblyResolutionSet assemblySet; if (_key2AssemblySets.TryGetValue(assemblyKeys[i], out assemblySet)) { result.Add(assemblySet); } else { dialog.AddError(""); return(false); } } return(true); }
internal bool Introspect(IMessageDialog dialog) { if (!Guid.IsNullOrWhiteSpace()) { return(true); } dialog.AddError("An addin must at least have a valid guid to be identified!"); return(false); }
public bool TryRegisterAddin(IMessageDialog dialog, ObjectId addinId, AddinResolution newAddin, out AddinResolution existingAddin) { if (_guid2Addins.TryGetValue(addinId.Guid, out existingAddin)) { dialog.AddError(string.Format("An addin with the identity [{0}] already exists!", addinId.Guid)); return(false); } _guid2Addins.Add(addinId.Guid, newAddin); return(true); }
// returns null if sucessful, otherwise return an existing ExtensionPointResolution public bool TryRegisterExtension(IMessageDialog dialog, ExtensionResolution newExtension, out ExtensionResolution existingExtension) { if (_path2Extensions.TryGetValue(newExtension.Head.Path, out existingExtension)) { dialog.AddError(""); return(false); } _path2Extensions.Add(newExtension.Head.Path, newExtension); return(true); }
// returns null if sucessful, otherwise return an existing ExtensionPointResolution public bool TryRegisterExtensionBuilder(IMessageDialog dialog, ExtensionBuilderResolution newExtensionBuilder, out ExtensionBuilderResolution existingExtensionBuilder) { if (_path2ExtensionBuilders.TryGetValue(newExtensionBuilder.Path, out existingExtensionBuilder)) { dialog.AddError(""); return(false); } _path2ExtensionBuilders.Add(newExtensionBuilder.Path, newExtensionBuilder); return(true); }
// returns null if sucessful, otherwise return an existing ExtensionPointResolution public bool TryRegisterExtensionPoint(IMessageDialog dialog, ExtensionPointResolution newExtensionPoint, out ExtensionPointResolution existingExtensionPoint) { if (_id2ExtensionPoints.TryGetValue(newExtensionPoint.Id, out existingExtensionPoint)) { dialog.AddError(""); return(false); } _id2ExtensionPoints.Add(newExtensionPoint.Id, newExtensionPoint); return(true); }
internal bool Introspect(IMessageDialog dialog) { bool result = true; if (TypeName.IsNullOrWhiteSpace()) { dialog.AddError("An activator must at least provide a type name!"); result = false; } return(result); }
internal virtual bool Introspect(IMessageDialog dialog) { var result = true; if (TypeName.IsNullOrWhiteSpace()) { dialog.AddError("An extension point must at least provide a type name!"); result = false; } return(result | DoIntrospect(dialog, "extension point")); }
internal override bool Introspect(IMessageDialog dialog) { var result = true; if (ExtensionPointId == null) { dialog.AddError("An id of extension point must have an parent!"); result = false; } if (ParentPath == null) { dialog.AddError("An extension builder must have an parent!"); result = false; } if (TypeName.IsNullOrWhiteSpace()) { dialog.AddError("An extension builder must at least provide a type name!"); result = false; } return(result | DoIntrospect(dialog, "extension builder")); }
/// <summary> /// The extension type of the extension builders must be the same as that of its parent. /// </summary> internal static bool ExtensionTypeMatchesParent(this ExtensionBuilderResolution eb, IMessageDialog dialog, TypeResolution extensionType) { var result = extensionType.Equals(eb.Parent.ExtensionType); // can not use ReferenceEquals here!!!! var parenteEb = eb.Parent as ExtensionBuilderResolution; if (!result) { dialog.AddError(string.Format( "The extension type of extension builder must match that of its parent, while the extension type of the extension builder [{0}] is [{1}], and that of its parent [{2}] is [{3}], which does not match!", eb.Path, extensionType.TypeName, parenteEb != null ? parenteEb.Path : eb.Parent.Id, eb.Parent.ExtensionType.TypeName)); } return(result); }
protected bool DoIntrospect(IMessageDialog dialog, string name) { var result = true; if (Id.IsNullOrWhiteSpace()) { dialog.AddError("An " + name + " must at least have an id to be identified!"); result = false; } if (Id.Contains(SysConstants.PathSeparator)) { dialog.AddError("An " + name + " id can not contain [/]!"); result = false; } if (_children != null) { foreach (var child in _children) { result &= child.Introspect(dialog); } } return(result); }
bool IsManifest(IMessageDialog dialog, string manifestFile) { var xmlDoc = new XmlDocument(); try { xmlDoc.Load(manifestFile); } catch (Exception ex) { // log dialog.AddError(ex.Message); return(false); } XmlNode rootNode = xmlDoc.DocumentElement; if (rootNode == null || !Addin.Equals(XmlHelper.GetNodeName(rootNode)) || !rootNode.HasChildNodes) { return(false); } _headerNode = rootNode[Header]; if (_headerNode == null) { return(false); } var extensionsNode = rootNode[Extensions]; if (extensionsNode == null) { return(false); } _declarationNode = extensionsNode[Declaration]; _implementationNode = extensionsNode[Implementation]; if ((_declarationNode == null || _declarationNode.NodeType != XmlNodeType.Element || !_declarationNode.HasChildNodes) && (_implementationNode == null || _implementationNode.NodeType != XmlNodeType.Element || !_implementationNode.HasChildNodes)) { return(false); } else { return(true); } }
bool TryLoadAndRegisterAssembly(IMessageDialog dialog, AssemblyResolution assembly) { if (!assembly.TryLoad()) { dialog.AddError(""); return(false); } AssemblyResolutionSet assemblySet; if (!_key2AssemblySets.TryGetValue(assembly.AssemblyKey, out assemblySet)) { assemblySet = new AssemblyResolutionSet(); _key2AssemblySets[assembly.AssemblyKey] = assemblySet; } //if (assembly.AssemblyFile.Uid != UidProvider.InvalidAssemblyUid) // _uid2AssemblySets.Add(assembly.AssemblyFile.Uid, assemblySet); assemblySet.Add(assembly); return(true); }
internal bool TryParse(IMessageDialog dialog, AddinResolution addin, out AddinHeaderResolution result) { result = new AddinHeaderResolution { AddinId = new AddinId() }; try { result.AddinId.Guid = new Guid(Guid); result.AddinCategory = AddinCategory == null ? Core.AddinCategory.User : (AddinCategory)Enum.Parse(typeof(AddinCategory), AddinCategory); result.Enabled = Enabled == null ? true : bool.Parse(Enabled); result.Version = Version == null ? _defaultVersion : new Version(Version); result.CompatVersion = CompatVersion == null ? _defaultVersion : new Version(CompatVersion); result.FriendName = FriendName; result.Url = Url; result.Properties = Properties; result.Description = Description; return(true); } catch (Exception e) { dialog.AddError(e.Message); return(false); } }
// Notes that this method will load the related assembly which defined the IExtensionBuilder implementation into memory. /// <summary> /// The required properties of extension builder (marked by ExtensionDataAttribute) must be provided by the extension data. /// </summary> /// <returns></returns> internal static bool ExtensionDataMatchesExtensionBuilder(this ExtensionResolution ex, IMessageDialog dialog, ResolutionContext ctx, ConvertionManager convertionManager) { var ebProperties = ex.ExtensionBuilder.Type.GetSettableRuntimeProperties(); if (ebProperties == null) { return(true); } var data = ex.Data; foreach (var ebProp in ebProperties) { var propName = ebProp.Name; string propInput; if (!data.TryGetString(propName, out propInput)) { var exPropAttrib = ebProp.GetCustomAttribute <ExtensionPropertyAttribute>(false, false); if (exPropAttrib != null && exPropAttrib.Required) { dialog.AddError("a required property is missing!"); return(false); } continue; } #region specific types if (ebProp.PropertyType == typeof(string)) { var holder = new StringHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } // convert to TypeId if (ebProp.PropertyType == typeof(TypeId)) { TypeResolution type; // a type dependency is introduced here. // should it be added to the current addin's reference set? if (!ctx.TryGetAddinType(ex.DeclaringAddin, propInput, out type)) { dialog.AddError(""); return(false); } var holder = new LazyTypeIdHolder(type); data.AddSerializableHolder(propName, holder); continue; } #endregion // convert to custom type (with an ObjectConverter registered in ConvertionManager). var objectConverter = convertionManager.TryGet(typeof(string), ebProp.PropertyType); if (objectConverter == null) { dialog.AddError("No converter is registered for !"); return(false); } // if an property value is provided for the property name, try to convert it. object propValue; if (!objectConverter.TryConvert(propInput, out propValue)) { dialog.AddError("The string [] can not be converted to !"); return(false); } #region common types if (ebProp.PropertyType == typeof(Int32)) { var holder = new Int32Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Boolean)) { var holder = new BooleanHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Version)) { var holder = new VersionHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(DateTime)) { var holder = new DateTimeHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Guid)) { var holder = new GuidHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(TimeSpan)) { var holder = new TimeSpanHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Int64)) { var holder = new Int64Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(UInt64)) { var holder = new UInt64Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(UInt32)) { var holder = new UInt32Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Int16)) { var holder = new Int16Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(UInt16)) { var holder = new UInt16Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Byte)) { var holder = new ByteHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(SByte)) { var holder = new SByteHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Char)) { var holder = new CharHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Decimal)) { var holder = new DecimalHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Double)) { var holder = new DoubleHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Single)) { var holder = new SingleHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } #endregion } return(true); }
// if we can find the referenced extension builder, the resolution is done. internal override ResolutionStatus Resolve(IMessageDialog dialog, ConvertionManager convertionManager, ResolutionContext ctx) { // Tries to get the parent if (Parent == null) { BaseExtensionPointResolution objParent; if (ParentIsExtensionPoint) { ExtensionPointResolution parent; if (!ctx.TryGetExtensionPoint(dialog, ParentPath, out parent)) { dialog.AddError(string.Format("Can not find the parent of the specified extension builder [{0}] with path [{1}]!", TypeName, ParentPath)); return(ResolutionStatus.Failed); } objParent = parent; } else { ExtensionBuilderResolution parent; if (!ctx.TryGetExtensionBuilder(dialog, ParentPath, out parent)) { dialog.AddError(string.Format("Can not find the parent of the specified extension builder [{0}] with path [{1}]!", TypeName, ParentPath)); return(ResolutionStatus.Failed); } objParent = parent; } if (objParent.DeclaringAddin != null && !ReferenceEquals(objParent.DeclaringAddin, DeclaringAddin)) { if (objParent.Type == null) { return(ResolutionStatus.Pending); } // The parent of current extension builder is not defined in the same addin as it is, // so we needs to add its declaring addin as a reference (the type of the parent must // be loaded before this extension builder at start up). AssemblyResolutionSet assemblySet; if (!ctx.TryGetAssemblySet(objParent.Type.Assembly.AssemblyKey, out assemblySet)) { throw new Exception(); } DeclaringAddin.AddReferencedAssemblySet(assemblySet); } Parent = objParent; } if (_referenced == null) { var referenced = TryFindReferencedExtensionBuilder(Parent, Id); if (referenced == null) { if (!ctx.TryGetExtensionBuilder(dialog, Path, out referenced)) { return(ResolutionStatus.Failed); } } if (referenced.DeclaringAddin != null && !ReferenceEquals(referenced.DeclaringAddin, DeclaringAddin)) { if (referenced.Type == null) { return(ResolutionStatus.Pending); } // The parent of current extension builder is not defined in the same addin as it is, // so we needs to add its declaring addin as a reference (the type of the parent must // be loaded before this extension builder at start up). AssemblyResolutionSet assemblySet; if (!ctx.TryGetAssemblySet(referenced.Type.Assembly.AssemblyKey, out assemblySet)) { throw new Exception(); } DeclaringAddin.AddReferencedAssemblySet(assemblySet); } _referenced = referenced; } return(ResolveAddin(Parent) | _referenced.Resolve(dialog, convertionManager, ctx)); }
internal override ResolutionStatus Resolve(IMessageDialog dialog, ConvertionManager convertionManager, ResolutionContext ctx) { if (Parent != null && ExtensionBuilder != null) { // all dependencies that might be declared in other addins has been retrieved. if (Head.SiblingId != null && Sibling != null) { return(ResolveAddin(ExtensionBuilder) | ResolveAddin(Parent) | ResolveAddin(Sibling)); } if (Head.SiblingId == null) { return(ResolveAddin(ExtensionBuilder) | ResolveAddin(Parent)); } } if (Parent == null) { ExtensionPointResolution epResolution; if (!ctx.TryGetExtensionPoint(dialog, Head.ParentPath, out epResolution)) { ExtensionResolution exResolution; if (!ctx.TryGetExtension(dialog, Head.ParentPath, out exResolution)) { dialog.AddError(string.Format("Can not find the parent of the specified extension [{0}] with path [{1}]!", Head.Path, Head.ParentPath)); return(ResolutionStatus.Failed); } if (!ReferenceEquals(exResolution.DeclaringAddin, DeclaringAddin)) { var ep = GetExtensionPointFor(exResolution); if (ep == null) { return(ResolutionStatus.Pending); // the extension point is probably not available right now. } DeclaringAddin.AddExtendedExtensionPoint(ep); } Parent = exResolution; } else { if (!ReferenceEquals(epResolution.DeclaringAddin, DeclaringAddin)) { DeclaringAddin.AddExtendedExtensionPoint(epResolution); } Parent = epResolution; } // The metadata of the parent (extension point or another extension) must be loaded before this extension, // so we needs to add its declaring addin as a dependency. if (!ReferenceEquals(Parent.DeclaringAddin, DeclaringAddin)) { DeclaringAddin.AddExtendedAddin(Parent.DeclaringAddin); } } if (ExtensionBuilder == null) { ExtensionBuilderResolution eb; if (!ctx.TryGetExtensionBuilder(dialog, Head.ExtensionBuilderPath, out eb)) { dialog.AddError(string.Format("Can not find the extension builder of the specified extension [{0}] with path [{1}]!", Head.Path, Head.ExtensionBuilderPath)); return(ResolutionStatus.Failed); } // The type of extension builder must be loaded before this extension, and it might not defined in the same // addin as current extension (ex), so we needs to add its declaring addin as a reference. // !!!Note that the extension point type must loaded before this extension too, but we'll let the extension // builder to refer to it. if (!ReferenceEquals(eb.DeclaringAddin, DeclaringAddin)) { if (eb.Type == null) { return(ResolutionStatus.Pending); } if (!ReferenceEquals(eb.Type.Assembly.DeclaringAddin, DeclaringAddin)) { AssemblyResolutionSet assemblySet; if (!ctx.TryGetAssemblySet(eb.Type.Assembly.AssemblyKey, out assemblySet)) { throw new Exception(); } DeclaringAddin.AddReferencedAssemblySet(assemblySet); } } ExtensionBuilder = eb; } if (Head.SiblingId != null && Sibling == null) { ExtensionResolution sibling; if (!ctx.TryGetExtension(dialog, Head.SiblingPath, out sibling)) { dialog.AddError(string.Format("Can not find the sibling extension of the specified extension [{0}] with path [{1}]!", Head.Path, Head.SiblingPath)); return(ResolutionStatus.Failed); } Sibling = sibling; // The metadata of the sibling extension must be loaded before this extension, so we needs to add its declaring // addin as a dependency. if (!ReferenceEquals(sibling.DeclaringAddin, DeclaringAddin)) { DeclaringAddin.AddExtendedAddin(sibling.DeclaringAddin); } } if (!ApplyRules(dialog, ctx, convertionManager)) { return(ResolutionStatus.Failed); } return(Sibling != null ? ResolveAddin(ExtensionBuilder) | ResolveAddin(Parent) | ResolveAddin(Sibling) : ResolveAddin(ExtensionBuilder) | ResolveAddin(Parent)); }