예제 #1
0
        // 根据 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;
        }
예제 #2
0
        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);
 }
예제 #8
0
 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);
 }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
 /// <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));
 }
예제 #15
0
        // 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));
 }
예제 #18
0
        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);
        }
예제 #19
0
 /// <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));
 }
예제 #21
0
 internal static bool InheritFromCompositeExtensionBuilderInterface(
     this TypeConstrainedResolvable eb, ResolutionResult resolutionResult, ResolutionContext ctx, out TypeResolution extensionType)
 {
     return(eb.Type.ImplementsCompositeExtensionBuilderInterface(resolutionResult, ctx, out extensionType));
 }
예제 #22
0
        /// <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);
        }
예제 #23
0
        // @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);
        }
예제 #28
0
        // 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);
        }
예제 #29
0
 /// <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));
 }