// 根据 existingAddin 的状态,将其 Assets 注册到 ResolutionContext AddinResolution DoRegisterExistingAddin(ResolutionResult resolutionResult, ResolutionContext ctx, AddinCollision addinCollision, AddinRecord existingAddin, AddinOperationStatus operationStatus) { //AddinRecord addinRecord; //if (!AddinRelationManager.TryGetAddin(existingAddin.Guid, out addinRecord)) // throw new InconsistentStateException(); ////AddinRelationManager.RemoveAddin(existingAddin); //AddinStorage.Remove(existingAddin); //if (operationStatus == AddinOperationStatus.NewOrUpdated) //{ // var ebs = existingAddin.GetAllExtensionBuilders(); // if (ebs != null) // { // foreach (var eb in ebs) // { // if (eb.ExtensionBuilderKind == ExtensionBuilderKind.Declared) // ctx.RegisterExtensionBuilderPath(eb.Uid, eb.GetPath()); // } // } // return null; //} var adnResolution = FromPersistentObject(existingAddin, operationStatus); TryRegisterAddin(resolutionResult, ctx, adnResolution, addinCollision); DoRegisterExistingAssets(resolutionResult, ctx, adnResolution); // if the operation status of an addin not equals to unaffected (i.e, directly/indirectly affected addin), it need to // be resolved, so we add it to the addin resolution list. return(adnResolution); //return operationStatus == AddinOperationStatus.Unaffected ? null : adnResolution; }
static bool ExtensionBuilderMatchesParent(ExtensionResolution ex, ResolutionResult resolutionResult) { var extensionBuilder = ex.ExtensionBuilder; var parentExtensionPoint = ex.Parent as ExtensionPointResolution; bool result; if (parentExtensionPoint != null) { result = parentExtensionPoint.Children != null && (parentExtensionPoint.Children.Contains(extensionBuilder) || parentExtensionPoint.Path == extensionBuilder.ParentPath); // 这是一个插件扩展了另外一个插件的 ExtensionSchema if (!result) { resolutionResult.AddError(string.Format("The extension builder of the extension [{0}] is not a child of that of the extension point [{1}]!", ex.Head.Path, parentExtensionPoint.Name)); } return(result); } var parentExtension = ex.Parent as ExtensionResolution; // the child extension builders of the extension builder for parent extension. result = parentExtension.ExtensionBuilder.Children.Contains(extensionBuilder) || parentExtension.ExtensionBuilder.Path == extensionBuilder.ParentPath; // 这是一个插件扩展了另外一个插件的 ExtensionSchema if (!result) { resolutionResult.AddError(string.Format("The extension builder of the extension [{0}] is not a child of that of its parent [{1}]!", ex.Head.Path, parentExtension.Head.Path)); } return(result); }
// Gets the required assembly references of @assembly that needs resolution. // By required, we mean assemblies that is not provided by runtime (.net, mono, etc) or the JointCode.AddIns.dll itself. // By default it refers to the GAC assemblies. public bool TryGetRequiredAssemblyReferences(ResolutionResult resolutionResult, AssemblyResolution assembly, out List <AssemblyResolutionSet> result) { var assemblyKeys = assembly.GetRequiredAssemblyReferences(); if (assemblyKeys == null) // get all referenced assemblies that is required. { 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 { resolutionResult.AddError("!!!!!!!!!!!"); return(false); } } return(true); }
// returns null if sucessful, otherwise return an existing ExtensionPointResolution public bool TryRegisterExtension(ResolutionResult resolutionResult, ExtensionResolution newExtension, out ExtensionResolution existingExtension) { if (_path2Extensions.TryGetValue(newExtension.Head.Path, out existingExtension)) { resolutionResult.AddError("##############"); return(false); } _path2Extensions.Add(newExtension.Head.Path, newExtension); return(true); }
public bool TryRegisterAddin(ResolutionResult resolutionResult, ObjectId addinId, AddinResolution newAddin, out AddinResolution existingAddin) { if (_guid2Addins.TryGetValue(addinId.Guid, out existingAddin)) { resolutionResult.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 TryRegisterExtensionPoint(ResolutionResult resolutionResult, ExtensionPointResolution newExtensionPoint, out ExtensionPointResolution existingExtensionPoint) { if (_path2ExtensionPoints.TryGetValue(newExtensionPoint.Path, out existingExtensionPoint)) { resolutionResult.AddError("@@@@@@@@@@@"); return(false); } _path2ExtensionPoints.Add(newExtensionPoint.Path, newExtensionPoint); return(true); }
// returns null if sucessful, otherwise return an existing ExtensionPointResolution public bool TryRegisterExtensionBuilder(ResolutionResult resolutionResult, ExtensionBuilderResolution newExtensionBuilder, out ExtensionBuilderResolution existingExtensionBuilder) { if (_path2ExtensionBuilders.TryGetValue(newExtensionBuilder.Path, out existingExtensionBuilder)) { resolutionResult.AddError("&&&&&&&&&&&&&&&&"); return(false); } _path2ExtensionBuilders.Add(newExtensionBuilder.Path, newExtensionBuilder); return(true); }
static bool HasRequiredExtensionProperties(ResolutionResult resolutionResult, IEnumerable <PropertyDefinition> ebProps) { foreach (var ebProp in ebProps) { if (ExtensionPropertyIsRequired(ebProp)) { resolutionResult.AddError("a required property is missing!"); return(false); } } return(true); }
protected bool TryRegisterAddin(ResolutionResult resolutionResult, ResolutionContext ctx, AddinResolution adnResolution, AddinCollision addinCollision) { AddinResolution existingAddin; if (ctx.TryRegisterAddin(resolutionResult, adnResolution.AddinId, adnResolution, out existingAddin)) { return(true); } var key = new AddinCollisionKey(existingAddin.Guid); addinCollision.Add(key, adnResolution, existingAddin); return(false); }
void DoRegisterExistingAssets(ResolutionResult resolutionResult, ResolutionContext ctx, AddinResolution adnResolution) { if (adnResolution.Assemblies != null) { foreach (var asm in adnResolution.Assemblies) { ctx.RegisterAssembly(resolutionResult, asm); } } if (adnResolution.ExtensionPoints != null) { foreach (var ep in adnResolution.ExtensionPoints) { ctx.RegisterExtensionPoint(ep); } } // get all extension builders defined under extension point and extension builder set var extensionBuilders = adnResolution.GetAllExtensionBuilders(); if (extensionBuilders != null) { foreach (var eb in extensionBuilders) { if (eb.ExtensionBuilderKind != ExtensionBuilderKind.Referenced) { ctx.RegisterExtensionBuilder(eb); } } } var extensions = adnResolution.GetAllExtensions(); if (extensions != null) { foreach (var ex in extensions) { ctx.RegisterExtension(ex); } } }
bool TryLoadAndRegisterAssembly(ResolutionResult resolutionResult, AssemblyResolution assembly) { if (!assembly.TryLoad()) { resolutionResult.AddError("Failed to load assembly file " + assembly.AssemblyFile.FilePath); return(false); } AssemblyResolutionSet assemblySet; if (!_key2AssemblySets.TryGetValue(assembly.AssemblyKey, out assemblySet)) { assemblySet = new AssemblyResolutionSet(); _key2AssemblySets[assembly.AssemblyKey] = assemblySet; } //if (assembly.AssemblyFile.Uid != UidStorage.InvalidAssemblyUid) // _uid2AssemblySets.Add(assembly.AssemblyFile.Uid, assemblySet); assemblySet.Add(assembly); return(true); }
static bool ExtensionDataMatchesExtensionProperties(ResolutionContext ctx, ConvertionManager convertionManager, ExtensionResolution ex, ResolutionResult resolutionResult, IEnumerable <PropertyDefinition> ebProps) { var data = ex.Data; if (ex is NewOrUpdatedExtensionResolution) { foreach (var ebProp in ebProps) { var propName = ebProp.Name; string propData; if (!data.TryGetString(propName, out propData)) { if (ExtensionPropertyIsRequired(ebProp)) { resolutionResult.AddError(string.Format("A required property [{0}] of extension builder [{1}] is not provided with a data!", ebProp.Name, ex.ExtensionBuilder.Type.TypeName)); return(false); } continue; } var propType = ebProp.PropertyType.SafeResolve(); DataTransformer dataTransformer; if (!ctx.TryGetDataTransformer(propType.Module.Assembly.FullName, propType.MetadataToken.ToInt32(), out dataTransformer)) { resolutionResult.AddError(string.Format("No data transformer is registered for type [{0}]!", propType.FullName)); return(false); } if (!dataTransformer.Transform(propName, propData, ctx, convertionManager, ex)) { resolutionResult.AddError(string.Format("Can not transform from value [{1}] to type [{0}]!", propType.FullName, propData)); return(false); } } } else { foreach (var ebProp in ebProps) { var propName = ebProp.Name; DataHolder dataHolder; if (!data.TryGetDataHolder(propName, out dataHolder)) { if (ExtensionPropertyIsRequired(ebProp)) { resolutionResult.AddError(string.Format("A required property [{0}] of extension builder [{1}] is not provided with a data!", ebProp.Name, ex.ExtensionBuilder.Type.TypeName)); return(false); } continue; } var propType = ebProp.PropertyType.SafeResolve(); DataTransformer dataTransformer; if (!ctx.TryGetDataTransformer(propType.Module.Assembly.FullName, propType.MetadataToken.ToInt32(), out dataTransformer)) { resolutionResult.AddError(string.Format("No data transformer is registered for type [{0}]!", propType.FullName)); return(false); } if (!dataTransformer.CanTransform(dataHolder)) { resolutionResult.AddError(string.Format("Can not transform from value [{1}] to type [{0}]!", propType.FullName, dataHolder.Value)); return(false); } } } return(true); }
/// <summary> /// The addin activator type must implement the IAddinActivator interface. /// </summary> internal static bool InheritFromAddinActivatorInterface( this TypeConstrainedResolvable resolvable, ResolutionResult resolutionResult, ResolutionContext ctx) { return(resolvable.Type.ImplementsAddinActivatorInterface(resolutionResult, ctx)); }
public bool TryGetExtension(ResolutionResult resolutionResult, string extensionPath, out ExtensionResolution extension) { return(_path2Extensions.TryGetValue(extensionPath, out extension)); }
// 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, ResolutionResult resolutionResult, ResolutionContext ctx, ConvertionManager convertionManager) { if (!ex.ExtensionBuilder.Type.HasProperties) { return(true); } var ebProps = ex.ExtensionBuilder.Type.Properties; return(ex.Data == null ? HasRequiredExtensionProperties(resolutionResult, ebProps) : ExtensionDataMatchesExtensionProperties(ctx, convertionManager, ex, resolutionResult, ebProps)); }
public bool TryGetExtensionBuilderPath(ResolutionResult resolutionResult, int extensionBuilderUid, out string extensionBuilderPath) { return(_uid2UpdatedExtensionBuilderPaths.TryGetValue(extensionBuilderUid, out extensionBuilderPath)); }
public bool TryGetExtensionBuilder(ResolutionResult resolutionResult, int extensionBuilderUid, out ExtensionBuilderResolution extensionBuilder) { return(_uid2ExtensionBuilders.TryGetValue(extensionBuilderUid, out extensionBuilder)); }
internal ResolutionStatus Resolve(ResolutionResult resolutionResult, ConvertionManager convertionManager, ResolutionContext ctx) { if (_resolutionStatus != ResolutionStatus.Pending) { return(_resolutionStatus); } if (AddinActivator != null) { var resolutionStatus = AddinActivator.Resolve(resolutionResult, convertionManager, ctx); if (resolutionStatus == ResolutionStatus.Failed) { _resolutionStatus = ResolutionStatus.Failed; return(_resolutionStatus); } } if (ExtensionPoints != null) { foreach (var extensionPoint in ExtensionPoints) { var resolutionStatus = extensionPoint.Resolve(resolutionResult, convertionManager, ctx); if (resolutionStatus == ResolutionStatus.Success) { continue; } else if (resolutionStatus == ResolutionStatus.Failed) { _resolutionStatus = ResolutionStatus.Failed; return(_resolutionStatus); } else { return(ResolutionStatus.Pending); } } } var extensionBuilders = GetAllExtensionBuilders(); if (extensionBuilders != null) { foreach (var extensionBuilder in extensionBuilders) { var resolutionStatus = extensionBuilder.Resolve(resolutionResult, convertionManager, ctx); if (resolutionStatus == ResolutionStatus.Success) { continue; } else if (resolutionStatus == ResolutionStatus.Failed) { _resolutionStatus = ResolutionStatus.Failed; return(_resolutionStatus); } else { return(ResolutionStatus.Pending); } } } var extensions = GetAllExtensions(); if (extensions != null) { foreach (var extension in extensions) { var resolutionStatus = extension.Resolve(resolutionResult, convertionManager, ctx); if (resolutionStatus == ResolutionStatus.Success) { continue; } else if (resolutionStatus == ResolutionStatus.Failed) { _resolutionStatus = ResolutionStatus.Failed; return(_resolutionStatus); } else { return(ResolutionStatus.Pending); } } } if (_referencedAssemblySets != null) { foreach (var referencedAssemblySet in _referencedAssemblySets) { var resolutionStatus = referencedAssemblySet.Resolve(resolutionResult, convertionManager, ctx); if (resolutionStatus == ResolutionStatus.Success) { continue; } else if (resolutionStatus == ResolutionStatus.Failed) { _resolutionStatus = ResolutionStatus.Failed; return(_resolutionStatus); } else { return(ResolutionStatus.Pending); } } } _resolutionStatus = ResolutionStatus.Success; return(_resolutionStatus); }
/// <summary> /// The extension point type must implement the IExtensionPoint{TExtension, TRoot} interface (with 2 generic parameters). /// </summary> internal static bool InheritFromExtensionPointInterface( this TypeConstrainedResolvable resolvable, ResolutionResult resolutionResult, ResolutionContext ctx, out TypeResolution extensionType) { return(resolvable.Type.ImplementsExtensionPointInterface(resolutionResult, ctx, out extensionType)); }
public bool TryGetExtensionPoint(ResolutionResult resolutionResult, string extensionPointPath, out ExtensionPointResolution result) { return(_path2ExtensionPoints.TryGetValue(extensionPointPath, out result)); }
internal static bool InheritFromCompositeExtensionBuilderInterface( this TypeConstrainedResolvable eb, ResolutionResult resolutionResult, ResolutionContext ctx, out TypeResolution extensionType) { return(eb.Type.ImplementsCompositeExtensionBuilderInterface(resolutionResult, ctx, out extensionType)); }
/// <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, ResolutionResult resolutionResult, TypeResolution extensionType) { var result = extensionType.Equals(eb.Parent.ExtensionType); // can not use ReferenceEquals here!!!! var parenteEb = eb.Parent as ExtensionBuilderResolution; if (!result) { resolutionResult.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.Name, eb.Parent.ExtensionType.TypeName)); } return(result); }
// @return: whether there is collisions. protected bool TryRegisterAssets(ResolutionResult resolutionResult, ResolutionContext ctx, AddinResolution adnResolution, AddinCollision addinCollision) { var success = true; if (adnResolution.Assemblies != null) { for (int i = 0; i < adnResolution.Assemblies.Count; i++) { var asm = adnResolution.Assemblies[i]; if (ctx.TryRegisterAssembly(resolutionResult, asm)) { continue; } // if the assembly loading (with mono.cecil) is failed, it's because this is not a valid managed assembly (might be a native library), // just remove it from the assembly list, and add it to the data file list instead. adnResolution.Assemblies.RemoveAt(i); i -= 1; adnResolution.DataFiles.Add(new DataFileResolution { FilePath = asm.AssemblyFile.FilePath }); } //foreach (var asm in adnResolution.Assemblies) // ctx.TryRegisterAssembly(resolutionResult, asm); } if (adnResolution.ExtensionPoints != null) { foreach (var extensionPoint in adnResolution.ExtensionPoints) { ExtensionPointResolution existingExtensionPoint; if (!ctx.TryRegisterExtensionPoint(resolutionResult, extensionPoint, out existingExtensionPoint)) { var key = new ExtensionPointCollisionKey(existingExtensionPoint.Name); addinCollision.Add(key, adnResolution, existingExtensionPoint.DeclaringAddin); success = false; } } } // get all extension builders defined under extension point and extension builder set var extensionBuilders = adnResolution.GetAllExtensionBuilders(); if (extensionBuilders != null) { foreach (var extensionBuilder in extensionBuilders) { if (extensionBuilder.ExtensionBuilderKind == ExtensionBuilderKind.Referenced) { continue; } ExtensionBuilderResolution existingExtensionBuilder; if (!ctx.TryRegisterExtensionBuilder(resolutionResult, extensionBuilder, out existingExtensionBuilder)) { var key = new ExtensionBuilderCollisionKey(existingExtensionBuilder.Name); addinCollision.Add(key, adnResolution, existingExtensionBuilder.DeclaringAddin); success = false; } } } var extensions = adnResolution.GetAllExtensions(); if (extensions != null) { foreach (var extension in extensions) { ExtensionResolution existingExtension; if (!ctx.TryRegisterExtension(resolutionResult, extension, out existingExtension)) { var key = new ExtensionCollisionKey(existingExtension.Head.Path); addinCollision.Add(key, adnResolution, existingExtension.DeclaringAddin); success = false; } } } return(success); }
public bool TryRegisterAssembly(ResolutionResult resolutionResult, AssemblyResolution assembly) { return(TryLoadAndRegisterAssembly(resolutionResult, assembly)); }
//public void RegisterApplicationAssembly(ResolutionResult resolutionResult, AssemblyResolution assembly) //{ // TryLoadAndRegisterAssembly(dialog, assembly); //} //public bool TryRegisterApplicationAssembly(ResolutionResult resolutionResult, string assembly) //{ // var asm = new AssemblyResolution(assembly); // return TryLoadAndRegisterAssembly(dialog, asm); //} public void RegisterAssembly(ResolutionResult resolutionResult, AssemblyResolution assembly) { TryLoadAndRegisterAssembly(resolutionResult, assembly); }
public bool TryGetExtensionBuilder(ResolutionResult resolutionResult, string extensionBuilderPath, out ExtensionBuilderResolution extensionBuilder) { return(_path2ExtensionBuilders.TryGetValue(extensionBuilderPath, out extensionBuilder)); }
internal override ResolutionResult Resolve(INameConvention nameConvention, ResolutionContext ctx, ScanFilePackResult scanFilePackResult) { var resolutionResult = new ResolutionResult(); // try parsing the new (or updated) addin manifests (configuration) var adnResolutions = TryParseAddins(nameConvention, resolutionResult, scanFilePackResult.ScanFilePacks); if (adnResolutions == null) { resolutionResult.NewAddinsFound = false; return(resolutionResult); } var addinCollision = new AddinCollision(); // try to register id of new addins at first, so that we can tell whether there are // any updated addins when registering that of the existing addins. foreach (var adnResolution in adnResolutions) { TryRegisterAddin(resolutionResult, ctx, adnResolution, addinCollision); } // register all assets of existing addins to the context (skipping updated addins) List <AddinResolution> resolableAddins = null; if (AddinStorage.AddinRecordCount > 0) { resolableAddins = RegisterExistingAssets(resolutionResult, ctx, addinCollision); } // try to register assets of new and updated addins to the context foreach (var adnResolution in adnResolutions) { TryRegisterAssets(resolutionResult, ctx, adnResolution, addinCollision); } if (resolableAddins != null) { adnResolutions.AddRange(resolableAddins); } // tries to resolve all addin, and make sure: // 1. there is no cirular dependencies between the resolved addins. // 2. the resolved addin list is sorted by the dependency. var resolvedAddins = TryResolveAddins(resolutionResult, ConvertionManager, ctx, adnResolutions); if (adnResolutions.Count > 0) { StoreUnresolvableAddins(adnResolutions); // 剩余的 adnResolutions 即为未成功解析的插件,此处也要将它们持久化 } if (ResolutionFailed(resolutionResult, ctx, resolvedAddins)) { resolutionResult.NewAddinsFound = false; return(resolutionResult); } // if there is any conflicting addins, trim them and all addins that depends on them. if (addinCollision.Count > 0) { TrimConflictingAddins(addinCollision, resolvedAddins); // recursively if (ResolutionFailed(resolutionResult, ctx, resolvedAddins)) { resolutionResult.NewAddinsFound = false; return(resolutionResult); } } // save all resolvable addin records to persistent file. StoreResolvedAddins(resolutionResult, ctx, resolvedAddins); PersistAddinStorage(resolutionResult); ctx.Dispose(); resolutionResult.NewAddinsFound = true; return(resolutionResult); }
// this method should split the existing addins into the following kind: // 1. updated addins // 2. unaffected addins // 3. directly affected addins // 4. indirectly affected addins // then, decide how to register assets of these addins and whether they need resolution, according to each kind. // and finally, return the addin list that need to be resolved. protected List <AddinResolution> RegisterExistingAssets(ResolutionResult resolutionResult, ResolutionContext ctx, AddinCollision addinCollision) { // ================================================= // 1. 首先确定 AddinStorage 中各个现有 addin 的状态:未受影响的、已更新的、间接受影响的 // check whether there are updated addins. // and if there are any, mark their operation status as updated. List <AddinRecord> updatedAddins = null; for (int i = AddinStorage.AddinRecordCount - 1; i >= 0; i--) { var existingAddin = AddinStorage.Get(i); var addinId = existingAddin.AddinId; AddinResolution adnResolution; // 如果 ResolutionContext 中已存在相同 guid 的插件,则表明这是一个更新的插件 if (!ctx.TryGetAddin(addinId, out adnResolution)) { continue; } AddinStorage.Remove(existingAddin); //AddinRelationManager.RemoveRelationMap(existingAddin); //adnResolution.OperationStatus = AddinOperationStatus.Updated; updatedAddins = updatedAddins ?? new List <AddinRecord>(); updatedAddins.Add(existingAddin); } if (AddinStorage.AddinRecordCount == 0) { return(null); // all addins are updated addins. } // mark directly affected and indirectly affected addins. List <AddinRecord> directlyAffectedAddins = null, indirectlyAffectedAddins = null; if (updatedAddins != null) { directlyAffectedAddins = AddinRelationManager.TryGetAffectingAddins(updatedAddins); if (directlyAffectedAddins != null) { indirectlyAffectedAddins = AddinRelationManager.TryGetAllAffectingAddins(directlyAffectedAddins); //if (indirectlyAffectedAddins != null) //{ // for (int i = indirectlyAffectedAddins.Count - 1; i >= 0; i--) // { // if (directlyAffectedAddins.Contains(indirectlyAffectedAddins[i])) // indirectlyAffectedAddins.RemoveAt(i); // } //} } } // ================================================= // 2. 根据 AddinStorage 中各个现有 addin 的状态,将它们注册到 ResolutionContext if (updatedAddins != null) { foreach (var updatedAddin in updatedAddins) { var ebs = updatedAddin.GetAllExtensionBuilders(); if (ebs != null) { foreach (var eb in ebs) { if (eb.ExtensionBuilderKind == ExtensionBuilderKind.Declared) { // 将已更新插件的 ExtensionBuilderPath 映射注册到 context。 // 因为在解析 Extension 时,是根据 ExtensionBuilderPath 查找 ExtensionBuilder 的,但对于 [directlyAffectedAddins 插件的 Extension] 来说,它们并不 // 保存自身依赖的 updateAddins 的 ExtensionBuilder 的 ExtensionBuilderPath。 // 所以,只能在解析前先将 updateAddins 的 ExtensionBuilder 的 ExtensionBuilderPath 注册到 context,后面解析 [directlyAffectedAddins 插件的 Extension] // 时,才能通过 uid 获得目标 ExtensionBuilder 的 path,继而找到 ExtensionBuilder ctx.RegisterExtensionBuilderPath(eb.Uid, eb.GetPath()); } } } } } List <AddinResolution> resolableAddins = null; // decide how to register assets of these addins and whether to resolve these addins according to their operation status. if (directlyAffectedAddins != null) { foreach (var directlyAffectedAddin in directlyAffectedAddins) { AddinStorage.Remove(directlyAffectedAddin); var resolvableAddin = DoRegisterExistingAddin(resolutionResult, ctx, addinCollision, directlyAffectedAddin, AddinOperationStatus.DirectlyAffected); resolableAddins = resolableAddins ?? new AddinResolutionSet(); resolableAddins.Add(resolvableAddin); } } if (indirectlyAffectedAddins != null) { foreach (var indirectlyAffectedAddin in indirectlyAffectedAddins) { AddinStorage.Remove(indirectlyAffectedAddin); var resolvableAddin = DoRegisterExistingAddin(resolutionResult, ctx, addinCollision, indirectlyAffectedAddin, AddinOperationStatus.IndirectlyAffected); resolableAddins = resolableAddins ?? new AddinResolutionSet(); resolableAddins.Add(resolvableAddin); } } // since the updated, directly affected and indirectly affected, they are all removed, so the rest is unaffected for (int i = AddinStorage.AddinRecordCount - 1; i >= 0; i--) { var unaffectedAddin = AddinStorage.Get(i); AddinStorage.Remove(unaffectedAddin); var resolvableAddin = DoRegisterExistingAddin(resolutionResult, ctx, addinCollision, unaffectedAddin, AddinOperationStatus.Unaffected); resolableAddins = resolableAddins ?? new AddinResolutionSet(); resolableAddins.Add(resolvableAddin); } return(resolableAddins); }
/// <summary> /// The extension builders used to build the current extension and the sibling extension (if exists) must be a child of that /// of the parent extension or extension point. /// </summary> internal static bool ExtensionBuildersMatchParent(this ExtensionResolution ex, ResolutionResult resolutionResult) { return(ex.Sibling == null ? ExtensionBuilderMatchesParent(ex, resolutionResult) : ExtensionBuilderMatchesParent(ex, resolutionResult) && ExtensionBuilderMatchesParent(ex.Sibling, resolutionResult)); }