public override void ExtensionActivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
 {
     if (_reloadWorkaround.AppDomainRestartNeeded) {
         Logger.Information("ExtensionActivated: Module \"{0}\" has changed, forcing AppDomain restart", extension.Id);
         ctx.RestartAppDomain = _reloadWorkaround.AppDomainRestartNeeded;
     }
 }
예제 #2
0
        /// <summary>
        /// 激活引用。
        /// </summary>
        /// <param name="context">扩展装载上下文。</param>
        /// <param name="referenceEntry">引用条目。</param>
        public override void ReferenceActivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry)
        {
            if (string.IsNullOrEmpty(referenceEntry.VirtualPath))
            {
                return;
            }

            var sourceFileName = _applicationFolder.MapPath(referenceEntry.VirtualPath);

            //如果程序集文件不存在或者比新的旧则复制新的程序集文件到依赖目录。
            var copyAssembly =
                !_assemblyProbingFolder.AssemblyExists(new AssemblyDescriptor(referenceEntry.Name)) ||
                File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(new AssemblyDescriptor(referenceEntry.Name));

            if (!copyAssembly)
            {
                return;
            }
            context.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(new AssemblyDescriptor(referenceEntry.Name), sourceFileName));

            //如果程序集已经被加载,需要重新启动AppDomain
            if (!_hostEnvironment.IsAssemblyLoaded(referenceEntry.Name))
            {
                return;
            }
            Logger.Information("ReferenceActivated: 引用 \"{0}\" 激活新的程序集文件加载,迫使AppDomain重启", referenceEntry.Name);
            context.RestartAppDomain = true;
        }
        public override void ReferenceActivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry)
        {
            //Note: This is the same implementation as "PrecompiledExtensionLoader"
            if (string.IsNullOrEmpty(referenceEntry.VirtualPath))
            {
                return;
            }

            string sourceFileName = _virtualPathProvider.MapPath(referenceEntry.VirtualPath);

            // Copy the assembly if it doesn't exist or if it is older than the source file.
            bool copyAssembly =
                !_assemblyProbingFolder.AssemblyExists(referenceEntry.Name) ||
                File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(referenceEntry.Name);

            if (copyAssembly)
            {
                context.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(referenceEntry.Name, sourceFileName));

                // We need to restart the appDomain if the assembly is loaded
                if (_hostEnvironment.IsAssemblyLoaded(referenceEntry.Name))
                {
                    Logger.Information("ReferenceActivated: Reference \"{0}\" is activated with newer file and its assembly is loaded, forcing AppDomain restart", referenceEntry.Name);
                    context.RestartAppDomain = true;
                }
            }
        }
 public override void ExtensionActivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
 {
     if (_reloadWorkaround.AppDomainRestartNeeded)
     {
         Logger.Information("ExtensionActivated: Module \"{0}\" has changed, forcing AppDomain restart", extension.Id);
         ctx.RestartAppDomain = _reloadWorkaround.AppDomainRestartNeeded;
     }
 }
        private void ProcessExtensionReference(ExtensionLoadingContext context, string referenceName, ICollection <DependencyReferenceDescriptor> activatedReferences)
        {
            //如果参考是一个扩展已经被处理,使用相同的装载机扩展,因为给定的扩展名应具有独特的装载机在整个应用程序加载
            var bestExtensionReference = context.ProcessedExtensions.ContainsKey(referenceName) ?
                                         context.ProcessedExtensions[referenceName] :
                                         null;

            //激活扩展引用
            if (bestExtensionReference != null)
            {
                activatedReferences.Add(new DependencyReferenceDescriptor
                {
                    LoaderName  = bestExtensionReference.Loader.Name,
                    Name        = referenceName,
                    VirtualPath = bestExtensionReference.VirtualPath
                });

                return;
            }

            //跳过来自 "~/bin" 的引用。
            if (_buildManager.HasReferencedAssembly(referenceName))
            {
                return;
            }

            //二进制引用
            var references = context.ReferencesByName.ContainsKey(referenceName) ?
                             context.ReferencesByName[referenceName] :
                             Enumerable.Empty <ExtensionReferenceProbeEntry>();

            var bestBinaryReference = references
                                      .Where(entry => !string.IsNullOrEmpty(entry.VirtualPath))
                                      .Select(entry => new { Entry = entry, LastWriteTimeUtc = _virtualPathProvider.GetFileLastWriteTimeUtc(entry.VirtualPath) })
                                      .OrderBy(e => e.LastWriteTimeUtc)
                                      .ThenBy(e => e.Entry.Name)
                                      .FirstOrDefault();

            //激活二进制引用
            if (bestBinaryReference == null)
            {
                return;
            }

            if (!context.ProcessedReferences.ContainsKey(bestBinaryReference.Entry.Name))
            {
                context.ProcessedReferences.Add(bestBinaryReference.Entry.Name, bestBinaryReference.Entry);
                bestBinaryReference.Entry.Loader.ReferenceActivated(context, bestBinaryReference.Entry);
            }
            activatedReferences.Add(new DependencyReferenceDescriptor
            {
                LoaderName  = bestBinaryReference.Entry.Loader.Name,
                Name        = bestBinaryReference.Entry.Name,
                VirtualPath = bestBinaryReference.Entry.VirtualPath
            });
        }
 private void DeleteAssembly(ExtensionLoadingContext ctx, string moduleName) {
     var assemblyPath = _virtualPathProvider.Combine("~/bin", moduleName + ".dll");
     if (_virtualPathProvider.FileExists(assemblyPath)) {
         ctx.DeleteActions.Add(
             () => {
                 Logger.Information("ExtensionRemoved: Deleting assembly \"{0}\" from bin directory (AppDomain will restart)", moduleName);
                 File.Delete(_virtualPathProvider.MapPath(assemblyPath));
             });
         ctx.RestartAppDomain = true;
     }
 }
        private void ProcessContextCommands(ExtensionLoadingContext ctx)
        {
            Logger.Information("执行的加载扩展所需的操作列表...");
            foreach (var action in ctx.DeleteActions)
            {
                action();
            }

            foreach (var action in ctx.CopyActions)
            {
                action();
            }
        }
        private void DeleteAssembly(ExtensionLoadingContext ctx, string moduleName)
        {
            var assemblyPath = _virtualPathProvider.Combine("~/bin", moduleName + ".dll");

            if (_virtualPathProvider.FileExists(assemblyPath))
            {
                ctx.DeleteActions.Add(
                    () => {
                    Logger.Information("ExtensionRemoved: Deleting assembly \"{0}\" from bin directory (AppDomain will restart)", moduleName);
                    File.Delete(_virtualPathProvider.MapPath(assemblyPath));
                });
                ctx.RestartAppDomain = true;
            }
        }
        public override void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency) {
            if (_assemblyProbingFolder.AssemblyExists(dependency.Name)) {
                ctx.DeleteActions.Add(
                    () => {
                        Logger.Information("ExtensionRemoved: Deleting assembly \"{0}\" from probing directory", dependency.Name);
                        _assemblyProbingFolder.DeleteAssembly(dependency.Name);
                    });

                // We need to restart the appDomain if the assembly is loaded
                if (_hostEnvironment.IsAssemblyLoaded(dependency.Name)) {
                    Logger.Information("ExtensionRemoved: Module \"{0}\" is removed and its assembly is loaded, forcing AppDomain restart", dependency.Name);
                    ctx.RestartAppDomain = true;
                }
            }
        }
예제 #10
0
        private void DeleteAssembly(ExtensionLoadingContext ctx, string moduleName)
        {
            var assemblyPath = _virtualPathProvider.Combine("~/bin", moduleName + ".dll");

            if (!_virtualPathProvider.FileExists(assemblyPath))
            {
                return;
            }
            ctx.DeleteActions.Add(
                () =>
            {
                Logger.Information("ExtensionRemoved: 从 bin 目录删除程序集 \"{0}\"(AppDomain将重新启动)", moduleName);
                _virtualPathProvider.DeleteFile(assemblyPath);
            });
            ctx.RestartAppDomain = true;
        }
        public override void ExtensionActivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension) {
            string sourceFileName = _virtualPathProvider.MapPath(GetAssemblyPath(extension));

            // Copy the assembly if it doesn't exist or if it is older than the source file.
            bool copyAssembly =
                !_assemblyProbingFolder.AssemblyExists(extension.Id) ||
                File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(extension.Id);

            if (copyAssembly) {
                ctx.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(extension.Id, sourceFileName));

                // We need to restart the appDomain if the assembly is loaded
                if (_hostEnvironment.IsAssemblyLoaded(extension.Id)) {
                    Logger.Information("ExtensionRemoved: Module \"{0}\" is activated with newer file and its assembly is loaded, forcing AppDomain restart", extension.Id);
                    ctx.RestartAppDomain = true;
                }
            }
        }
        public override void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency)
        {
            if (_assemblyProbingFolder.AssemblyExists(dependency.Name))
            {
                ctx.DeleteActions.Add(
                    () => {
                    Logger.Information("ExtensionRemoved: Deleting assembly \"{0}\" from probing directory", dependency.Name);
                    _assemblyProbingFolder.DeleteAssembly(dependency.Name);
                });

                // We need to restart the appDomain if the assembly is loaded
                if (_hostEnvironment.IsAssemblyLoaded(dependency.Name))
                {
                    Logger.Information("ExtensionRemoved: Module \"{0}\" is removed and its assembly is loaded, forcing AppDomain restart", dependency.Name);
                    ctx.RestartAppDomain = true;
                }
            }
        }
        private string GetExtensionHash(ExtensionLoadingContext context, DependencyDescriptor dependencyDescriptor)
        {
            var hash = new Hash();

            hash.AddStringInvariant(dependencyDescriptor.Name);

            foreach (var virtualpathDependency in context.ProcessedExtensions[dependencyDescriptor.Name].VirtualPathDependencies)
            {
                hash.AddDateTime(GetVirtualPathModificationTimeUtc(context.VirtualPathModficationDates, virtualpathDependency));
            }

            foreach (var reference in dependencyDescriptor.References)
            {
                hash.AddStringInvariant(reference.Name);
                hash.AddString(reference.LoaderName);
                hash.AddDateTime(GetVirtualPathModificationTimeUtc(context.VirtualPathModficationDates, reference.VirtualPath));
            }

            return(hash.Value);
        }
        public override void ExtensionActivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
        {
            string sourceFileName = _virtualPathProvider.MapPath(GetAssemblyPath(extension));

            // Copy the assembly if it doesn't exist or if it is older than the source file.
            bool copyAssembly =
                !_assemblyProbingFolder.AssemblyExists(extension.Id) ||
                File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(extension.Id);

            if (copyAssembly)
            {
                ctx.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(extension.Id, sourceFileName));

                // We need to restart the appDomain if the assembly is loaded
                if (_hostEnvironment.IsAssemblyLoaded(extension.Id))
                {
                    Logger.Information("ExtensionRemoved: Module \"{0}\" is activated with newer file and its assembly is loaded, forcing AppDomain restart", extension.Id);
                    ctx.RestartAppDomain = true;
                }
            }
        }
예제 #15
0
        /// <summary>
        /// 扩展删除。
        /// </summary>
        /// <param name="context">扩展装载上下文。</param>
        /// <param name="dependency">依赖项描述符。</param>
        public override void ExtensionRemoved(ExtensionLoadingContext context, DependencyDescriptor dependency)
        {
            if (!_assemblyProbingFolder.AssemblyExists(new AssemblyDescriptor(dependency.Name)))
            {
                return;
            }

            context.DeleteActions.Add(
                () =>
            {
                Logger.Information("ExtensionRemoved: 删除在探测目录中的程序集 \"{0}\"", dependency.Name);
                _assemblyProbingFolder.DeleteAssembly(dependency.Name);
            });

            //如果程序集已经被加载,需要重新启动AppDomain
            if (!_hostEnvironment.IsAssemblyLoaded(dependency.Name))
            {
                return;
            }
            Logger.Information("ExtensionRemoved: 模块\"{0}\"被删除,它的程序集加载,迫使AppDomain重启", dependency.Name);
            context.RestartAppDomain = true;
        }
예제 #16
0
        /// <summary>
        /// 扩展停用。
        /// </summary>
        /// <param name="context">扩展装载上下文。</param>
        /// <param name="descriptor">扩展描述符条目。</param>
        public override void ExtensionDeactivated(ExtensionLoadingContext context, ExtensionDescriptorEntry descriptor)
        {
            if (!_assemblyProbingFolder.AssemblyExists(new AssemblyDescriptor(descriptor.Id)))
            {
                return;
            }

            context.DeleteActions.Add(
                () =>
            {
                Logger.Information("ExtensionDeactivated: 删除在探测目录中的程序集 \"{0}\"", descriptor.Id);
                _assemblyProbingFolder.DeleteAssembly(descriptor.Id);
            });

            //如果程序集已经被加载,需要重新启动AppDomain
            if (!_hostEnvironment.IsAssemblyLoaded(descriptor.Id))
            {
                return;
            }
            Logger.Information("ExtensionDeactivated: 模块 \"{0}\" 已停用,它的程序集已经被加载,迫使AppDomain重启", descriptor.Id);
            context.RestartAppDomain = true;
        }
예제 #17
0
        /// <summary>
        /// 扩展激活。
        /// </summary>
        /// <param name="context">扩展装载上下文。</param>
        /// <param name="descriptor">扩展描述符条目。</param>
        public override void ExtensionActivated(ExtensionLoadingContext context, ExtensionDescriptorEntry descriptor)
        {
            var sourceFileName = _applicationFolder.MapPath(GetAssemblyPath(descriptor));

            //如果程序集文件不存在或者比新的旧则复制新的程序集文件到依赖目录。
            var copyAssembly =
                !_assemblyProbingFolder.AssemblyExists(new AssemblyDescriptor(descriptor.Id)) ||
                File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(new AssemblyDescriptor(descriptor.Id));

            if (!copyAssembly)
            {
                return;
            }
            context.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(new AssemblyDescriptor(descriptor.Id), sourceFileName));

            //如果程序集已经被加载,需要重新启动AppDomain
            if (!_hostEnvironment.IsAssemblyLoaded(descriptor.Id))
            {
                return;
            }
            Logger.Information("ExtensionRemoved: 模块 \"{0}\" 激活新的程序集文件加载,迫使AppDomain重启", descriptor.Id);
            context.RestartAppDomain = true;
        }
 /// <summary>
 /// 扩展停用。
 /// </summary>
 /// <param name="context">扩展装载上下文。</param>
 /// <param name="descriptor">扩展描述符条目。</param>
 public override void ExtensionDeactivated(ExtensionLoadingContext context, ExtensionDescriptorEntry descriptor)
 {
     DeleteAssembly(context, descriptor.Id);
 }
예제 #19
0
 public virtual void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency) { }
예제 #20
0
 public void ExtensionActivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
 {
 }
 public void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency)
 {
     throw new NotImplementedException();
 }
예제 #22
0
 /// <summary>
 /// 扩展删除。
 /// </summary>
 /// <param name="context">扩展装载上下文。</param>
 /// <param name="dependency">依赖项描述符。</param>
 public virtual void ExtensionRemoved(ExtensionLoadingContext context, DependencyDescriptor dependency)
 {
 }
 public override void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency) {
 }
        /// <summary>
        /// 扩展停用。
        /// </summary>
        /// <param name="context">扩展装载上下文。</param>
        /// <param name="descriptor">扩展描述符条目。</param>
        public override void ExtensionDeactivated(ExtensionLoadingContext context, ExtensionDescriptorEntry descriptor)
        {
            if (!_assemblyProbingFolder.AssemblyExists(new AssemblyDescriptor(descriptor.Id)))
                return;

            context.DeleteActions.Add(
                () =>
                {
                    Logger.Information("ExtensionDeactivated: 删除在探测目录中的程序集 \"{0}\"", descriptor.Id);
                    _assemblyProbingFolder.DeleteAssembly(descriptor.Id);
                });

            //如果程序集已经被加载,需要重新启动AppDomain
            if (!_hostEnvironment.IsAssemblyLoaded(descriptor.Id))
                return;
            Logger.Information("ExtensionDeactivated: 模块 \"{0}\" 已停用,它的程序集已经被加载,迫使AppDomain重启", descriptor.Id);
            context.RestartAppDomain = true;
        }
        /// <summary>
        /// 扩展删除。
        /// </summary>
        /// <param name="context">扩展装载上下文。</param>
        /// <param name="dependency">依赖项描述符。</param>
        public override void ExtensionRemoved(ExtensionLoadingContext context, DependencyDescriptor dependency)
        {
            if (!_assemblyProbingFolder.AssemblyExists(new AssemblyDescriptor(dependency.Name)))
                return;

            context.DeleteActions.Add(
                () =>
                {
                    Logger.Information("ExtensionRemoved: 删除在探测目录中的程序集 \"{0}\"", dependency.Name);
                    _assemblyProbingFolder.DeleteAssembly(dependency.Name);
                });

            //如果程序集已经被加载,需要重新启动AppDomain
            if (!_hostEnvironment.IsAssemblyLoaded(dependency.Name))
                return;
            Logger.Information("ExtensionRemoved: 模块\"{0}\"被删除,它的程序集加载,迫使AppDomain重启", dependency.Name);
            context.RestartAppDomain = true;
        }
        private IEnumerable <DependencyReferenceDescriptor> ProcessExtensionReferences(ExtensionLoadingContext context, ExtensionProbeEntry activatedExtension)
        {
            if (activatedExtension == null)
            {
                return(Enumerable.Empty <DependencyReferenceDescriptor>());
            }

            var referenceNames = (context.ReferencesByModule.ContainsKey(activatedExtension.Descriptor.Id) ?
                                  context.ReferencesByModule[activatedExtension.Descriptor.Id] :
                                  Enumerable.Empty <ExtensionReferenceProbeEntry>())
                                 .Select(r => r.Name)
                                 .Distinct(StringComparer.OrdinalIgnoreCase);

            var referencesDecriptors = new List <DependencyReferenceDescriptor>();

            foreach (var referenceName in referenceNames)
            {
                ProcessExtensionReference(context, referenceName, referencesDecriptors);
            }

            return(referencesDecriptors);
        }
        private void ProcessExtension(ExtensionLoadingContext context, ExtensionDescriptorEntry extension)
        {
            var extensionProbes = context.AvailableExtensionsProbes.ContainsKey(extension.Id) ?
                                  context.AvailableExtensionsProbes[extension.Id] :
                                  Enumerable.Empty <ExtensionProbeEntry>();

            var extensionProbeEntries = extensionProbes as ExtensionProbeEntry[] ?? extensionProbes.ToArray();

            if (Logger.IsEnabled(LogLevel.Debug))
            {
                Logger.Debug("加载扩展 \"{0}\": ", extension.Id);
                foreach (var probe in extensionProbeEntries)
                {
                    Logger.Debug("  Loader: {0}", probe.Loader.Name);
                    Logger.Debug("    VirtualPath: {0}", probe.VirtualPath);
                    Logger.Debug("    VirtualPathDependencies: {0}", string.Join(", ", probe.VirtualPathDependencies));
                }
            }

            var moduleReferences =
                context.AvailableExtensions
                .Where(e =>
                       context.ReferencesByModule.ContainsKey(extension.Id) &&
                       context.ReferencesByModule[extension.Id].Any(r => StringComparer.OrdinalIgnoreCase.Equals(e.Id, r.Name)))
                .ToList();

            var processedModuleReferences =
                moduleReferences
                .Where(e => context.ProcessedExtensions.ContainsKey(e.Id))
                .Select(e => context.ProcessedExtensions[e.Id])
                .ToList();

            var activatedExtension = extensionProbeEntries.FirstOrDefault(
                e => e.Loader.IsCompatibleWithModuleReferences(extension, processedModuleReferences)
                );

            var previousDependency = context.PreviousDependencies.FirstOrDefault(
                d => StringComparer.OrdinalIgnoreCase.Equals(d.Name, extension.Id)
                );

            if (activatedExtension == null)
            {
                Logger.Warning("没有找到装载机来装载扩展 \"{0}\"!", extension.Id);
            }

            var references = ProcessExtensionReferences(context, activatedExtension);

            foreach (var loader in _loaders)
            {
                if (activatedExtension != null && activatedExtension.Loader.Name == loader.Name)
                {
                    Logger.Information("使用装载机 \"{1}\" 来激活扩展 \"{0}\"", activatedExtension.Descriptor.Id, loader.Name);
                    loader.ExtensionActivated(context, extension);
                }
                else if (previousDependency != null && previousDependency.LoaderName == loader.Name)
                {
                    Logger.Information("使用装载机 \"{1}\" 来停用扩展 \"{0}\"", previousDependency.Name, loader.Name);
                    loader.ExtensionDeactivated(context, extension);
                }
            }

            if (activatedExtension != null)
            {
                context.NewDependencies.Add(new DependencyDescriptor
                {
                    Name        = extension.Id,
                    LoaderName  = activatedExtension.Loader.Name,
                    VirtualPath = activatedExtension.VirtualPath,
                    References  = references
                });
            }

            //跟踪哪些装载机,我们使用的每一个扩展
            //这将需要从其他相关的扩展处理参考
            context.ProcessedExtensions.Add(extension.Id, activatedExtension);
        }
예제 #28
0
 /// <summary>
 /// 扩展停用。
 /// </summary>
 /// <param name="context">扩展装载上下文。</param>
 /// <param name="descriptor">扩展描述符条目。</param>
 public virtual void ExtensionDeactivated(ExtensionLoadingContext context, ExtensionDescriptorEntry descriptor)
 {
 }
예제 #29
0
 /// <summary>
 /// 扩展删除。
 /// </summary>
 /// <param name="context">扩展装载上下文。</param>
 /// <param name="dependency">依赖项描述符。</param>
 public virtual void ExtensionRemoved(ExtensionLoadingContext context, FileSystems.Dependencies.DependencyDescriptor dependency)
 {
 }
 public override void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency)
 {
 }
        private IEnumerable<DependencyReferenceDescriptor> ProcessExtensionReferences(ExtensionLoadingContext context, ExtensionProbeEntry activatedExtension)
        {
            if (activatedExtension == null)
                return Enumerable.Empty<DependencyReferenceDescriptor>();

            var referenceNames = (context.ReferencesByModule.ContainsKey(activatedExtension.Descriptor.Id) ?
                context.ReferencesByModule[activatedExtension.Descriptor.Id] :
                Enumerable.Empty<ExtensionReferenceProbeEntry>())
                .Select(r => r.Name)
                .Distinct(StringComparer.OrdinalIgnoreCase);

            var referencesDecriptors = new List<DependencyReferenceDescriptor>();
            foreach (var referenceName in referenceNames)
            {
                ProcessExtensionReference(context, referenceName, referencesDecriptors);
            }

            return referencesDecriptors;
        }
        /// <summary>
        /// 扩展激活。
        /// </summary>
        /// <param name="context">扩展装载上下文。</param>
        /// <param name="descriptor">扩展描述符条目。</param>
        public override void ExtensionActivated(ExtensionLoadingContext context, ExtensionDescriptorEntry descriptor)
        {
            var sourceFileName = _applicationFolder.MapPath(GetAssemblyPath(descriptor));

            //如果程序集文件不存在或者比新的旧则复制新的程序集文件到依赖目录。
            var copyAssembly =
                !_assemblyProbingFolder.AssemblyExists(new AssemblyDescriptor(descriptor.Id)) ||
                File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(new AssemblyDescriptor(descriptor.Id));

            if (!copyAssembly)
                return;
            context.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(new AssemblyDescriptor(descriptor.Id), sourceFileName));

            //如果程序集已经被加载,需要重新启动AppDomain
            if (!_hostEnvironment.IsAssemblyLoaded(descriptor.Id))
                return;
            Logger.Information("ExtensionRemoved: 模块 \"{0}\" 激活新的程序集文件加载,迫使AppDomain重启", descriptor.Id);
            context.RestartAppDomain = true;
        }
        public override void ReferenceActivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry) {
            //Note: This is the same implementation as "PrecompiledExtensionLoader"
            if (string.IsNullOrEmpty(referenceEntry.VirtualPath))
                return;

            string sourceFileName = _virtualPathProvider.MapPath(referenceEntry.VirtualPath);

            // Copy the assembly if it doesn't exist or if it is older than the source file.
            bool copyAssembly =
                !_assemblyProbingFolder.AssemblyExists(referenceEntry.Name) ||
                File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(referenceEntry.Name);

            if (copyAssembly) {
                context.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(referenceEntry.Name, sourceFileName));

                // We need to restart the appDomain if the assembly is loaded
                if (_hostEnvironment.IsAssemblyLoaded(referenceEntry.Name)) {
                    Logger.Information("ReferenceActivated: Reference \"{0}\" is activated with newer file and its assembly is loaded, forcing AppDomain restart", referenceEntry.Name);
                    context.RestartAppDomain = true;
                }
            }
        }
        /// <summary>
        /// 激活引用。
        /// </summary>
        /// <param name="context">扩展装载上下文。</param>
        /// <param name="referenceEntry">引用条目。</param>
        public override void ReferenceActivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry)
        {
            if (string.IsNullOrEmpty(referenceEntry.VirtualPath))
                return;

            var sourceFileName = _applicationFolder.MapPath(referenceEntry.VirtualPath);

            //如果程序集文件不存在或者比新的旧则复制新的程序集文件到依赖目录。
            var copyAssembly =
                !_assemblyProbingFolder.AssemblyExists(new AssemblyDescriptor(referenceEntry.Name)) ||
                File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(new AssemblyDescriptor(referenceEntry.Name));

            if (!copyAssembly)
                return;
            context.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(new AssemblyDescriptor(referenceEntry.Name), sourceFileName));

            //如果程序集已经被加载,需要重新启动AppDomain
            if (!_hostEnvironment.IsAssemblyLoaded(referenceEntry.Name))
                return;
            Logger.Information("ReferenceActivated: 引用 \"{0}\" 激活新的程序集文件加载,迫使AppDomain重启", referenceEntry.Name);
            context.RestartAppDomain = true;
        }
예제 #35
0
 /// <summary>
 /// 扩展停用。
 /// </summary>
 /// <param name="context">扩展装载上下文。</param>
 /// <param name="descriptor">扩展描述符条目。</param>
 public virtual void ExtensionDeactivated(ExtensionLoadingContext context, ExtensionDescriptorEntry descriptor)
 {
 }
예제 #36
0
 public void ExtensionDeactivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
 {
 }
 public void ExtensionDeactivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
 {
     throw new NotImplementedException();
 }
        private void ProcessExtension(ExtensionLoadingContext context, ExtensionDescriptorEntry extension)
        {
            var extensionProbes = context.AvailableExtensionsProbes.ContainsKey(extension.Id) ?
                context.AvailableExtensionsProbes[extension.Id] :
                Enumerable.Empty<ExtensionProbeEntry>();

            var extensionProbeEntries = extensionProbes as ExtensionProbeEntry[] ?? extensionProbes.ToArray();
            if (Logger.IsEnabled(LogLevel.Debug))
            {
                Logger.Debug("加载扩展 \"{0}\": ", extension.Id);
                foreach (var probe in extensionProbeEntries)
                {
                    Logger.Debug("  Loader: {0}", probe.Loader.Name);
                    Logger.Debug("    VirtualPath: {0}", probe.VirtualPath);
                    Logger.Debug("    VirtualPathDependencies: {0}", string.Join(", ", probe.VirtualPathDependencies));
                }
            }

            var moduleReferences =
                context.AvailableExtensions
                    .Where(e =>
                           context.ReferencesByModule.ContainsKey(extension.Id) &&
                           context.ReferencesByModule[extension.Id].Any(r => StringComparer.OrdinalIgnoreCase.Equals(e.Id, r.Name)))
                    .ToList();

            var processedModuleReferences =
                moduleReferences
                .Where(e => context.ProcessedExtensions.ContainsKey(e.Id))
                .Select(e => context.ProcessedExtensions[e.Id])
                .ToList();

            var activatedExtension = extensionProbeEntries.FirstOrDefault(
                e => e.Loader.IsCompatibleWithModuleReferences(extension, processedModuleReferences)
                );

            var previousDependency = context.PreviousDependencies.FirstOrDefault(
                d => StringComparer.OrdinalIgnoreCase.Equals(d.Name, extension.Id)
                );

            if (activatedExtension == null)
            {
                Logger.Warning("没有找到装载机来装载扩展 \"{0}\"!", extension.Id);
            }

            var references = ProcessExtensionReferences(context, activatedExtension);

            foreach (var loader in _loaders)
            {
                if (activatedExtension != null && activatedExtension.Loader.Name == loader.Name)
                {
                    Logger.Information("使用装载机 \"{1}\" 来激活扩展 \"{0}\"", activatedExtension.Descriptor.Id, loader.Name);
                    loader.ExtensionActivated(context, extension);
                }
                else if (previousDependency != null && previousDependency.LoaderName == loader.Name)
                {
                    Logger.Information("使用装载机 \"{1}\" 来停用扩展 \"{0}\"", previousDependency.Name, loader.Name);
                    loader.ExtensionDeactivated(context, extension);
                }
            }

            if (activatedExtension != null)
            {
                context.NewDependencies.Add(new DependencyDescriptor
                {
                    Name = extension.Id,
                    LoaderName = activatedExtension.Loader.Name,
                    VirtualPath = activatedExtension.VirtualPath,
                    References = references
                });
            }

            //跟踪哪些装载机,我们使用的每一个扩展
            //这将需要从其他相关的扩展处理参考
            context.ProcessedExtensions.Add(extension.Id, activatedExtension);
        }
 public void ReferenceDeactivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry)
 {
     throw new NotImplementedException();
 }
        private void ProcessContextCommands(ExtensionLoadingContext ctx)
        {
            Logger.Information("执行的加载扩展所需的操作列表...");
            foreach (var action in ctx.DeleteActions)
            {
                action();
            }

            foreach (var action in ctx.CopyActions)
            {
                action();
            }
        }
예제 #41
0
 public void ReferenceDeactivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry)
 {
 }
예제 #42
0
 /// <summary>
 /// 扩展停用。
 /// </summary>
 /// <param name="context">扩展装载上下文。</param>
 /// <param name="descriptor">扩展描述符条目。</param>
 public override void ExtensionDeactivated(ExtensionLoadingContext context, ExtensionDescriptorEntry descriptor)
 {
     DeleteAssembly(context, descriptor.Id);
 }
 private void DeleteAssembly(ExtensionLoadingContext ctx, string moduleName)
 {
     var assemblyPath = _virtualPathProvider.Combine("~/bin", moduleName + ".dll");
     if (!_virtualPathProvider.FileExists(assemblyPath))
         return;
     ctx.DeleteActions.Add(
         () =>
         {
             Logger.Information("ExtensionRemoved: 从 bin 目录删除程序集 \"{0}\"(AppDomain将重新启动)", moduleName);
             _virtualPathProvider.DeleteFile(assemblyPath);
         });
     ctx.RestartAppDomain = true;
 }
 public override void ExtensionDeactivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
 {
     DeleteAssembly(ctx, extension.Id);
 }
 /// <summary>
 /// 扩展删除。
 /// </summary>
 /// <param name="context">扩展装载上下文。</param>
 /// <param name="dependency">依赖项描述符。</param>
 public override void ExtensionRemoved(ExtensionLoadingContext context, DependencyDescriptor dependency)
 {
     DeleteAssembly(context, dependency.Name);
 }
 public override void ExtensionDeactivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
 {
     DeleteAssembly(ctx, extension.Id);
 }
 public override void ExtensionDeactivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
 {
 }
 public override void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency)
 {
     DeleteAssembly(ctx, dependency.Name);
 }
예제 #49
0
 /// <summary>
 /// 扩展删除。
 /// </summary>
 /// <param name="context">扩展装载上下文。</param>
 /// <param name="dependency">依赖项描述符。</param>
 public override void ExtensionRemoved(ExtensionLoadingContext context, FileSystems.Dependencies.DependencyDescriptor dependency)
 {
     DeleteAssembly(context, dependency.Name);
 }
        private void ProcessExtensionReference(ExtensionLoadingContext context, string referenceName, ICollection<DependencyReferenceDescriptor> activatedReferences)
        {
            //如果参考是一个扩展已经被处理,使用相同的装载机扩展,因为给定的扩展名应具有独特的装载机在整个应用程序加载
            var bestExtensionReference = context.ProcessedExtensions.ContainsKey(referenceName) ?
                context.ProcessedExtensions[referenceName] :
                null;

            //激活扩展引用
            if (bestExtensionReference != null)
            {
                activatedReferences.Add(new DependencyReferenceDescriptor
                {
                    LoaderName = bestExtensionReference.Loader.Name,
                    Name = referenceName,
                    VirtualPath = bestExtensionReference.VirtualPath
                });

                return;
            }

            //跳过来自 "~/bin" 的引用。
            if (_buildManager.HasReferencedAssembly(referenceName))
                return;

            //二进制引用
            var references = context.ReferencesByName.ContainsKey(referenceName) ?
                context.ReferencesByName[referenceName] :
                Enumerable.Empty<ExtensionReferenceProbeEntry>();

            var bestBinaryReference = references
                .Where(entry => !string.IsNullOrEmpty(entry.VirtualPath))
                .Select(entry => new { Entry = entry, LastWriteTimeUtc = _virtualPathProvider.GetFileLastWriteTimeUtc(entry.VirtualPath) })
                .OrderBy(e => e.LastWriteTimeUtc)
                .ThenBy(e => e.Entry.Name)
                .FirstOrDefault();

            //激活二进制引用
            if (bestBinaryReference == null)
                return;

            if (!context.ProcessedReferences.ContainsKey(bestBinaryReference.Entry.Name))
            {
                context.ProcessedReferences.Add(bestBinaryReference.Entry.Name, bestBinaryReference.Entry);
                bestBinaryReference.Entry.Loader.ReferenceActivated(context, bestBinaryReference.Entry);
            }
            activatedReferences.Add(new DependencyReferenceDescriptor
            {
                LoaderName = bestBinaryReference.Entry.Loader.Name,
                Name = bestBinaryReference.Entry.Name,
                VirtualPath = bestBinaryReference.Entry.VirtualPath
            });
        }
예제 #51
0
 public void ReferenceDeactivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry)
 {
 }
        private string GetExtensionHash(ExtensionLoadingContext context, DependencyDescriptor dependencyDescriptor)
        {
            var hash = new Hash();
            hash.AddStringInvariant(dependencyDescriptor.Name);

            foreach (var virtualpathDependency in context.ProcessedExtensions[dependencyDescriptor.Name].VirtualPathDependencies)
            {
                hash.AddDateTime(GetVirtualPathModificationTimeUtc(context.VirtualPathModficationDates, virtualpathDependency));
            }

            foreach (var reference in dependencyDescriptor.References)
            {
                hash.AddStringInvariant(reference.Name);
                hash.AddString(reference.LoaderName);
                hash.AddDateTime(GetVirtualPathModificationTimeUtc(context.VirtualPathModficationDates, reference.VirtualPath));
            }

            return hash.Value;
        }