Beispiel #1
0
        //public AddinEngine() : this(AddinOptions.Create()) { }

        public AddinEngine(AddinOptions addinOptions)
        {
            _addinRelationManager   = new AddinRelationManager();
            _addinFramework         = new AddinFramework(addinOptions);
            _assemblyResolver       = new RuntimeAssemblyResolver(_addinFramework);
            _runtimeExtensionLoader = new RuntimeExtensionLoader(_assemblyResolver, _addinFramework.ExtensionPointFactory, _addinFramework.ExtensionBuilderFactory);
        }
 protected AddinResolver(AddinStorage addinStorage, AddinRelationManager addinRelationManager, ConvertionManager convertionManager)
 {
     AddinStorage         = addinStorage;
     AddinRelationManager = addinRelationManager;
     ConvertionManager    = convertionManager;
     _addinParsers        = new List <AddinParser> {
         new XmlAddinParser()
     };
 }
        // @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));
        }
Beispiel #4
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);
        }
 internal DefaultAddinResolver(AddinStorage addinStorage, AddinRelationManager addinRelationManager, ConvertionManager convertionManager)
     : base(addinStorage, addinRelationManager, convertionManager)
 {
 }