private void ProcessExtensionReference(ExtensionLoadingContext context,
                                               ExtensionProbeEntry activatedExtension,
                                               string referenceName,
                                               IList <DependencyReferenceDescriptor> activatedReferences)
        {
            // If the reference is an extension has been processed already, use the same loader as
            // that extension, since a given extension should be loaded with a unique loader for the
            // whole application
            var bestExtensionReference = context.ProcessedExtensions.ContainsKey(referenceName) ?
                                         context.ProcessedExtensions[referenceName] :
                                         null;

            // Activated the extension reference
            if (bestExtensionReference != null)
            {
                activatedReferences.Add(new DependencyReferenceDescriptor
                {
                    LoaderName  = bestExtensionReference.Loader.Name,
                    Name        = referenceName,
                    VirtualPath = bestExtensionReference.VirtualPath
                });

                return;
            }

            // Skip references from "~/bin"
            if (_buildManager.HasReferencedAssembly(referenceName))
            {
                return;
            }

            // Binary references
            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();

            // Activate the binary ref
            if (bestBinaryReference != null)
            {
                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
                });
                return;
            }
        }
        private void ProcessContextCommands(ExtensionLoadingContext ctx)
        {
            Logger.Information("Executing list of operations needed for loading extensions...");
            foreach (var action in ctx.DeleteActions)
            {
                action();
            }

            foreach (var action in ctx.CopyActions)
            {
                action();
            }
        }
        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);
        }
        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, activatedExtension, referenceName, referencesDecriptors);
            }

            return(referencesDecriptors);
        }
 public void ReferenceDeactivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry)
 {
     throw new NotImplementedException();
 }
 public void ExtensionDeactivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension)
 {
     throw new NotImplementedException();
 }
        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;
        }
        private void ProcessContextCommands(ExtensionLoadingContext ctx) {
            Logger.Information("Executing list of operations needed for loading extensions...");
            foreach (var action in ctx.DeleteActions) {
                action();
            }

            foreach (var action in ctx.CopyActions) {
                action();
            }
        }
        private void ProcessExtensionReference(ExtensionLoadingContext context,
            ExtensionProbeEntry activatedExtension,
            string referenceName,
            IList<DependencyReferenceDescriptor> activatedReferences) {

            // If the reference is an extension has been processed already, use the same loader as 
            // that extension, since a given extension should be loaded with a unique loader for the 
            // whole application
            var bestExtensionReference = context.ProcessedExtensions.ContainsKey(referenceName) ?
                context.ProcessedExtensions[referenceName] :
                null;

            // Activated the extension reference
            if (bestExtensionReference != null) {
                activatedReferences.Add(new DependencyReferenceDescriptor {
                    LoaderName = bestExtensionReference.Loader.Name,
                    Name = referenceName,
                    VirtualPath = bestExtensionReference.VirtualPath
                });

                return;
            }

            // Skip references from "~/bin"
            if (_buildManager.HasReferencedAssembly(referenceName))
                return;

            // Binary references
            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();

            // Activate the binary ref
            if (bestBinaryReference != null) {
                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
                });
                return;
            }
        }
        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, activatedExtension, referenceName, referencesDecriptors);
            }

            return referencesDecriptors;
        }
        private void ProcessExtension(ExtensionLoadingContext context, ExtensionDescriptor extension) {

            var extensionProbes = context.AvailableExtensionsProbes.ContainsKey(extension.Id) ?
                context.AvailableExtensionsProbes[extension.Id] :
                Enumerable.Empty<ExtensionProbeEntry>();

            if (Logger.IsEnabled(LogLevel.Debug)) {
                Logger.Debug("Loaders for extension \"{0}\": ", extension.Id);
                foreach (var probe in extensionProbes) {
                    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 = extensionProbes
                .Where(e => e.Loader.IsCompatibleWithModuleReferences(extension, processedModuleReferences))
                .FirstOrDefault();

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

            if (activatedExtension == null) {
                Logger.Warning("No loader found for extension \"{0}\"!", extension.Id);
            }

            var references = ProcessExtensionReferences(context, activatedExtension);

            foreach (var loader in _loaders) {
                if (activatedExtension != null && activatedExtension.Loader.Name == loader.Name) {
                    Logger.Information("Activating extension \"{0}\" with loader \"{1}\"", activatedExtension.Descriptor.Id, loader.Name);
                    loader.ExtensionActivated(context, extension);
                }
                else if (previousDependency != null && previousDependency.LoaderName == loader.Name) {
                    Logger.Information("Deactivating extension \"{0}\" from loader \"{1}\"", 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
                });
            }

            // Keep track of which loader we use for every extension
            // This will be needed for processing references from other dependent extensions
            context.ProcessedExtensions.Add(extension.Id, activatedExtension);
        }
        private void ProcessExtension(ExtensionLoadingContext context, ExtensionDescriptor extension)
        {
            var extensionProbes = context.AvailableExtensionsProbes.ContainsKey(extension.Id) ?
                                  context.AvailableExtensionsProbes[extension.Id] :
                                  Enumerable.Empty <ExtensionProbeEntry>();

            // materializes the list
            extensionProbes = extensionProbes.ToArray();

            if (Logger.IsEnabled(LogLevel.Debug))
            {
                Logger.Debug("Loaders for extension \"{0}\": ", extension.Id);
                foreach (var probe in extensionProbes)
                {
                    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 = extensionProbes.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("No loader found for extension \"{0}\"!", extension.Id);
            }

            var references = ProcessExtensionReferences(context, activatedExtension);

            foreach (var loader in _loaders)
            {
                if (activatedExtension != null && activatedExtension.Loader.Name == loader.Name)
                {
                    Logger.Information("Activating extension \"{0}\" with loader \"{1}\"", activatedExtension.Descriptor.Id, loader.Name);
                    loader.ExtensionActivated(context, extension);
                }
                else if (previousDependency != null && previousDependency.LoaderName == loader.Name)
                {
                    Logger.Information("Deactivating extension \"{0}\" from loader \"{1}\"", 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
                });
            }

            // Keep track of which loader we use for every extension
            // This will be needed for processing references from other dependent extensions
            context.ProcessedExtensions.Add(extension.Id, activatedExtension);
        }
 public void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency) {
     throw new NotImplementedException();
 }