コード例 #1
0
        void DoInstallOrUpdate(string addinProbingPath, string addinDirectory, MyFunc <ScanFilePack, ResolutionResult> func)
        {
            VerifyInitialized();

            var filePack = GetScanFilePack(addinProbingPath, addinDirectory);

            if (filePack == null)
            {
                return;
            }

            var result = func(filePack);

            if (result.HasMessage)
            {
                _addinFramework.MessageDialog.Show(result.GetFormattedString(), "Information");
            }

            if (result.NewAddinsFound)
            {
                _addinStorage = new AddinStorage(_addinFramework.FileSettings.StorageFilePath);
                var hasAddins = _addinStorage.ReadOrReset();
                if (hasAddins)
                {
                    _addinRelationManager.ResetRelationMaps(_addinStorage.AddinRecords);
                }
            }
        }
コード例 #2
0
 protected AddinResolver(AddinStorage addinStorage, AddinRelationManager addinRelationManager, ConvertionManager convertionManager)
 {
     AddinStorage         = addinStorage;
     AddinRelationManager = addinRelationManager;
     ConvertionManager    = convertionManager;
     _addinParsers        = new List <AddinParser> {
         new XmlAddinParser()
     };
 }
コード例 #3
0
        // tries to get addin files that needed to be scaned or re-scaned (manifest or any of assembly files updated).
        // excluding: those files that have been scanned the last time, if they are unchanged.
        ScanFilePackResult GetScanFilePacks(AddinStorage addinStorage)
        {
            if (addinStorage == null || (addinStorage.AddinRecordCount == 0 && addinStorage.InvalidAddinFilePackCount == 0))
            {
                return(FilePackService.GetScanFilePackResult(_addinFramework.FileSettings, null));
            }
            var existingFilePacks = GetExistingAddinFilePacks(addinStorage);

            return(FilePackService.GetScanFilePackResult(_addinFramework.FileSettings, existingFilePacks));
        }
コード例 #4
0
        /// <summary>
        /// Initializes the <see cref="AddinEngine"/>, but do not start any addins yet.
        /// This way you gain greater controls upon the addin system, for example you can find an addin by its name, subscribe to events of that addin, and then start it later.
        /// </summary>
        /// <param name="shouldRefresh">
        /// if this value is set to <c>true</c>, the <seealso cref="AddinEngine"/> will scan the addin probing directories for
        /// new and updated addins every time this method is called.
        /// otherwise, it will only scan the addin probing directories once.
        /// </param>
        /// <returns></returns>
        public bool Initialize(bool shouldRefresh)
        {
            if (_initialized)
            {
                return(true);
            }

            _addinStorage = new AddinStorage(_addinFramework.FileSettings.StorageFilePath);
            var hasAddins = _addinStorage.ReadOrReset();

            if (hasAddins)
            {
                _addinRelationManager.ResetRelationMaps(_addinStorage.AddinRecords);
            }

            if (shouldRefresh || !hasAddins)
            {
                var filePackResult = GetScanFilePacks(_addinStorage);
                if (filePackResult != null)
                {
                    var result = ParseAndResolveAddins(filePackResult);
                    if (result.HasMessage)
                    {
                        _addinFramework.MessageDialog.Show(result.GetFormattedString(), "Addin resolution information");
                    }
                    if (result.NewAddinsFound)
                    {
                        _addinStorage.Reset();
                        hasAddins = _addinStorage.Read();
                        if (hasAddins)
                        {
                            _addinRelationManager.ResetRelationMaps(_addinStorage.AddinRecords);
                        }
                    }
                }
            }

            if (!hasAddins)
            {
                return(false);
            }

            //_addinRelationManager.ResetRelationMaps(_addinStorage.AddinRecords);
            CreateAddins();
            _initialized = true;

            return(true);
        }
コード例 #5
0
        IEnumerable <AddinFilePack> GetExistingAddinFilePacks(AddinStorage addinStorage)
        {
            var existingFilePacks = new List <AddinFilePack>(addinStorage.AddinRecordCount + addinStorage.InvalidAddinFilePackCount);

            if (addinStorage.AddinRecordCount > 0)
            {
                foreach (var addin in addinStorage.AddinRecords)
                {
                    existingFilePacks.Add(addin.AddinFilePack);
                }
            }
            if (addinStorage.InvalidAddinFilePackCount > 0)
            {
                existingFilePacks.AddRange(addinStorage.InvalidAddinFilePacks);
            }

            return(existingFilePacks);
        }
コード例 #6
0
        // @return value: whether the persistence file has been updated.
        public ResolutionResult Resolve(INameConvention nameConvention, AddinFileSettings fileSettings, AssemblyLoadPolicy assemblyLoadPolicy,
                                        AddinStorage addinStorage, AddinRelationManager relationManager,
                                        ScanFilePackResult scanFilePackResult)
        {
            var ctx = new ResolutionContext();
            var cm  = new ConvertionManager();

            InitializeDataTransformers(ctx, cm);

            if (assemblyLoadPolicy.PrivateAssemblyProbingDirectories != null)
            {
                foreach (var privateAssemblyProbingDirectory in assemblyLoadPolicy.PrivateAssemblyProbingDirectories)
                {
                    AssemblyResolution.AddSearchDirectory(privateAssemblyProbingDirectory);
                }
            }

            var resolver = new DefaultAddinResolver(addinStorage, relationManager, cm);

            // 强制 ExtensionBuilder 节点应用 NameConvention
            return(resolver.Resolve(nameConvention, ctx, scanFilePackResult));
        }
コード例 #7
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);
        }
コード例 #8
0
 internal DefaultAddinResolver(AddinStorage addinStorage, AddinRelationManager addinRelationManager, ConvertionManager convertionManager)
     : base(addinStorage, addinRelationManager, convertionManager)
 {
 }