void DoRemoveRelationMap(AddinRecord addin) { _addinRecords.Remove(addin); //_guid2AddinRecords.Remove(addin.Guid); //_uid2AddinRecords.Remove(addin.Uid); if (addin.ExtensionPoints != null) { foreach (var extensionPoint in addin.ExtensionPoints) { _path2ExtensionPoints.Remove(extensionPoint.Path); } } if (addin.AssemblyFiles != null) { foreach (var assemblyFile in addin.AssemblyFiles) { AddinRecordSet addinSet; if (!_assemblyUid2AddinSets.TryGetValue(assemblyFile.Uid, out addinSet)) { continue; } if (addinSet.Remove(addin) && addinSet.Count == 0) { _assemblyUid2AddinSets.Remove(assemblyFile.Uid); } } } }
void DoAddRelationMap(AddinRecord addin) { //_uid2AddinRecords.Add(addin.Uid, addin); //_guid2AddinRecords.Add(addin.Guid, addin); _addinRecords.Add(addin); if (addin.AssemblyFiles != null) { foreach (var assemblyFile in addin.AssemblyFiles) { AddinRecordSet addinSet; if (!_assemblyUid2AddinSets.TryGetValue(assemblyFile.Uid, out addinSet)) { addinSet = new AddinRecordSet(); _assemblyUid2AddinSets.Add(assemblyFile.Uid, addinSet); } addinSet.Add(addin); } } if (addin.ExtensionPoints != null) { foreach (var extensionPoint in addin.ExtensionPoints) { extensionPoint.AddinRecord = addin; _path2ExtensionPoints.Add(extensionPoint.Path, extensionPoint); } } }
/// <summary> /// Get a list of addins that the sepecified addin directly depended (refers to or extends), whose status change will affect this addin. /// </summary> internal AddinRecordSet TryGetDependedAddins(AddinRecord addin) { var result = new AddinRecordSet(); if (addin.ExtendedAddins != null) { foreach (var extendedAddin in addin.ExtendedAddins) { result.Add(GetAddinByUid(extendedAddin.Uid)); } } if (addin.ReferencedAssemblies != null) { foreach (var referencedAssembly in addin.ReferencedAssemblies) { var referencedAddins = _assemblyUid2AddinSets[referencedAssembly.Uid]; var referencedAddin = referencedAddins.SelectFirst(); if (!result.Contains(referencedAddin)) { result.Add(referencedAddin); } } } return(result.Count > 0 ? result : null); }
/// <summary> /// Get all addins that directly/indirectly refers to or extends the sepecified addin, which will be affected by the /// status change of the later. /// </summary> internal AddinRecordSet TryGetAllAffectingAddins(AddinRecord addin) { var result = TryGetAffectingAddins(addin); if (result == null) { return(null); } for (int i = 0; i < result.Count; i++) { var subItems = TryGetAffectingAddins(result[i]); if (subItems == null) { continue; } foreach (var subItem in subItems) { if (!result.Contains(subItem)) { result.Add(subItem); } } } return(result.Count > 0 ? result : null); }
// get the direct references of an addin (not recursively) // the references of an addin is determined until the first time this method is called. bool DoTryGetReferencedAddins(AddinRecord addin, out List <AddinRecord> result) { result = null; //if (addin.ReferencedAssemblies == null) // return false; //result = new List<AddinRecord>(); //foreach (var referencedAssembly in addin.ReferencedAssemblies) //{ // AddinRecordSet referencedAddinSet; // if (!_assemblyUid2AddinSets.TryGetValue(referencedAssembly.Uid, out referencedAddinSet)) // throw new InconsistentStateException(string.Format("Can not find the referenced addin for an assembly of addin [{0}], which has been resolved successfully!", addin.AddinId.Guid)); // var referencedAddin = SelectReferencedAddin(referencedAddinSet); // if (referencedAddin == null) // throw new InconsistentStateException(string.Format("Can not find the referenced addin for an assembly of addin [{0}] which has been resolved successfully, because none of referenced addins is in enabled status!", addin.AddinId.Guid)); // if (!result.Contains(referencedAddin)) // result.Add(SelectReferencedAddin(referencedAddinSet)); //} //return result.Count > 0; return(false); }
/// <summary> /// Get all addins that the sepecified addin refers to (recursively). /// </summary> /// <returns></returns> internal bool TryGetAllReferencedAddins(AddinRecord addin, out List <AddinRecord> result) { result = null; List <AddinRecord> referencedAddins; if (!DoTryGetReferencedAddins(addin, out referencedAddins)) { return(false); } for (int i = 0; i < referencedAddins.Count; i++) { var referencedAddin = referencedAddins[i]; List <AddinRecord> subReferencedAddins; if (!DoTryGetReferencedAddins(referencedAddin, out subReferencedAddins)) { continue; } foreach (var subReferencedAddin in subReferencedAddins) { if (!referencedAddins.Contains(subReferencedAddin)) { referencedAddins.Add(subReferencedAddin); } } } result = referencedAddins; return(true); }
// 将 addinRecord 插入到 list 中,按其 Uid 排序,Uid 越小越靠前。 internal static void InsetAddinByUid(List <AddinRecord> list, AddinRecord addinRecord) { if (list.Count == 0) { list.Add(addinRecord); return; } if (list.Contains(addinRecord)) { return; } for (int i = 0; i < list.Count; i++) { var item = list[i]; // 插件 Uid 表示插件的依赖关系以及添加到应用程序的时间。依赖项越少、添加到应用程序的时间越早,Uid 越小。 if (addinRecord.Uid < item.Uid) { list.Insert(i, addinRecord); return; } } // 比所有现存插件的 Uid 都大,所以添加到末尾。 list.Add(addinRecord); }
// when other addins refers to the specified [assemblyFile], is the specified [addin] is the default selected addin bool IsDefaultSelectedAddinForAssembly(AssemblyFileRecord assemblyFile, AddinRecord addin) { AddinRecordSet adns; if (!_assemblyUid2AddinSets.TryGetValue(assemblyFile.Uid, out adns)) { throw new InvalidOperationException(); } return(ReferenceEquals(adns.SelectFirstOrNull(), addin)); }
///// <summary> ///// Determines whether the depended assembly located at the application base directory. ///// </summary> ///// <param name="assemblyDependency"></param> ///// <returns></returns> //internal bool HasApplicationAssembly(AssemblyDependency assemblyDependency) //{ // return false; //} //internal void AddApplicationAssembly(ApplicationAssemblyRecord applicationAssembly) //{ // _applicationAssemblies.Add(applicationAssembly); //} //internal void AddApplicationAssemblies(IEnumerable<ApplicationAssemblyRecord> applicationAssemblies) //{ // foreach (var applicationAssembly in applicationAssemblies) // _applicationAssemblies.Add(applicationAssembly); //} internal bool TryGetAddin(Guid guid, out AddinRecord addin) { for (int i = 0; i < _addinRecords.Count; i++) { var addinRecord = _addinRecords[i]; if (addinRecord.Guid == guid) { addin = addinRecord; return(true); } } addin = null; return(false); }
/// <summary> /// Get a list of addins that the sepecified addin extends directly (not recursively). /// </summary> internal bool TryGetExtendedAddins(AddinRecord addin, out List <AddinRecord> result) { if (addin.ExtendedAddins == null || addin.ExtendedAddins.Count == 0) { result = null; return(false); } result = new List <AddinRecord>(addin.ExtendedAddins.Count); for (int i = 0; i < addin.ExtendedAddins.Count; i++) { var ea = addin.ExtendedAddins[i]; var ad = GetAddinByUid(ea.Uid); result.Add(ad); } return(true); }
/// <summary> /// Get a list of addins that directly refers to or extends the sepecified addin, which will be affected by the /// status change of the later. /// </summary> /// <param name="addin">The addin that should be checked for affected addins.</param> /// <returns></returns> internal AddinRecordSet TryGetAffectingAddins(AddinRecord addin) { var result = new AddinRecordSet(); // 获取当前扩展了指定插件 (addin) 的现有插件 foreach (var existingAddin in _addinRecords) { if (!existingAddin.Enabled) { continue; } if (existingAddin.ExtendsAddin(addin.Uid)) { result.Add(existingAddin); } } // 获取当前引用了该插件 (addin) 程序集的其他现有插件 if (addin.AssemblyFiles != null) { foreach (var assemblyFile in addin.AssemblyFiles) { if (!IsDefaultSelectedAddinForAssembly(assemblyFile, addin)) { continue; // 如果当前插件 (addin) 并非被选为默认提供该程序集 (assemblyFile) 的插件,则不会有其他插件依赖当前插件 } foreach (var existingAddin in _addinRecords) { if (!existingAddin.RefersToAssembly(assemblyFile.Uid)) { continue; } if (!result.Contains(existingAddin)) { result.Add(existingAddin); } } } } return(result.Count > 0 ? result : null); }
internal void RemoveRelationMap(AddinRecord addin) { DoRemoveRelationMap(addin); }
internal void AddRelationMap(AddinRecord addin) { DoAddRelationMap(addin); }
void DoTryGetAffectingAddins(List <AddinRecord> result, List <AddinRecord> changedAddins, AddinRecord changedAddin) { // 获取当前扩展了指定插件 (changedAddin) 的现有插件 foreach (var existingAddin in _addinRecords) { if (!existingAddin.ExtendsAddin(changedAddin.Uid)) { continue; } if (!result.Contains(existingAddin) && !changedAddins.Contains(existingAddin)) { result.Add(existingAddin); } } // 获取当前引用了指定插件 (changedAddin) 的程序集的其他现有插件 if (changedAddin.AssemblyFiles != null) { foreach (var assemblyFile in changedAddin.AssemblyFiles) { //if (AllAddinsProvidedAssemblyAreAffected(assemblyFile, changedAddins, result)) // continue; // 如果所有提供当前程序集的插件都已发生变更 if (!IsDefaultSelectedAddinForAssembly(assemblyFile, changedAddin)) { continue; // 如果当前插件 (changedAddin) 并非被选为默认提供该程序集 (assemblyFile) 的插件,则不会有其他插件依赖当前插件 } foreach (var existingAddin in _addinRecords) { if (!existingAddin.RefersToAssembly(assemblyFile.Uid)) { continue; } if (!result.Contains(existingAddin) && !changedAddins.Contains(existingAddin)) { result.Add(existingAddin); } } } } }
/// <summary> /// Get a list of addins that the sepecified addin refers to directly (not recursively). /// </summary> internal bool TryGetReferencedAddins(AddinRecord addin, out List <AddinRecord> result) { return(DoTryGetReferencedAddins(addin, out result)); }