/// <summary> /// Handles any exception occurred in the module Initialization process, /// logs the error using the <see cref="ILog"/> and throws a <see cref="ModuleInitializeException"/>. /// This method can be overridden to provide a different behavior. /// </summary> /// <param name="moduleInfo">The module metadata where the error happenened.</param> /// <param name="exception">The exception thrown that is the cause of the current error.</param> /// <exception cref="ModuleInitializeException"></exception> public virtual void HandleModuleInitializationError(ModuleInfo moduleInfo, Exception exception) { if (moduleInfo == null) throw new ArgumentNullException("moduleInfo"); if (exception == null) throw new ArgumentNullException("exception"); Exception moduleException; if (exception is ModuleInitializeException) { moduleException = exception; } else { if (moduleInfo.ModuleInstance != null) { var assemblyName = moduleInfo.ModuleInstance.GetType().Assembly.FullName; moduleException = new ModuleInitializeException(moduleInfo.ModuleName, assemblyName, exception.Message, exception); } else { moduleException = new ModuleInitializeException(moduleInfo.ModuleName, exception.Message, exception); } } var manifestModule = moduleInfo as ManifestModuleInfo; if(manifestModule != null) { manifestModule.Errors.Add(exception.ToString()); } _loggerFacade.Error(moduleException.ToString()); throw moduleException; }
/// <summary> /// Return all dependencies with best compatible version /// </summary> /// <param name="moduleInfo"></param> /// <returns></returns> protected override IEnumerable<ModuleInfo> GetDependentModulesInner(ModuleInfo moduleInfo) { var retVal = new List<ModuleInfo>(); var manifestModule = moduleInfo as ManifestModuleInfo; if (moduleInfo == null) { throw new ModularityException("moduleInfo not ManifestModuleInfo type"); } //get all dependency modules with all versions var dependecies = base.GetDependentModulesInner(moduleInfo).OfType<ManifestModuleInfo>(); foreach (var dependencyVersions in dependecies.GroupBy(x => x.Id)) { var dependency = manifestModule.Dependencies.First(x => x.Id == dependencyVersions.Key); var allCompatibleDependencies = dependencyVersions.Where(x => dependency.Version.IsCompatibleWithBySemVer(x.Version)).OrderByDescending(x => x.Version); var latestCompatibleDependency = allCompatibleDependencies.FirstOrDefault(x => x.IsInstalled); //If dependency not installed need find latest compatible version if (latestCompatibleDependency == null) { latestCompatibleDependency = allCompatibleDependencies.FirstOrDefault(); } if (latestCompatibleDependency != null) { retVal.Add(latestCompatibleDependency); } } return retVal; }
/// <summary> /// Evaluates the <see cref="ModuleInfo.Ref"/> property to see if the current typeloader will be able to retrieve the <paramref name="moduleInfo"/>. /// Returns true if the <see cref="ModuleInfo.Ref"/> property starts with "file://", because this indicates that the file /// is a local file. /// </summary> /// <param name="moduleInfo">Module that should have it's type loaded.</param> /// <returns> /// <see langword="true"/> if the current typeloader is able to retrieve the module, otherwise <see langword="false"/>. /// </returns> /// <exception cref="ArgumentNullException">An <see cref="ArgumentNullException"/> is thrown if <paramref name="moduleInfo"/> is null.</exception> public bool CanLoadModuleType(ModuleInfo moduleInfo) { if (moduleInfo == null) { throw new System.ArgumentNullException("moduleInfo"); } return moduleInfo.Ref != null && moduleInfo.Ref.StartsWith(RefFilePrefix, StringComparison.Ordinal); }
/// <summary> /// Initializes a new instance of the <see cref="LoadModuleCompletedEventArgs"/> class. /// </summary> /// <param name="moduleInfo">The module info.</param> /// <param name="error">Any error that occurred during the call.</param> public LoadModuleCompletedEventArgs(ModuleInfo moduleInfo, Exception error) { if (moduleInfo == null) { throw new ArgumentNullException("moduleInfo"); } this.ModuleInfo = moduleInfo; this.Error = error; }
/// <summary> /// Initializes a new instance of the <see cref="ModuleDownloadProgressChangedEventArgs"/> class. /// </summary> /// <param name="moduleInfo">The module info.</param> /// <param name="bytesReceived">The bytes received.</param> /// <param name="totalBytesToReceive">The total bytes to receive.</param> public ModuleDownloadProgressChangedEventArgs(ModuleInfo moduleInfo, long bytesReceived, long totalBytesToReceive) : base(CalculateProgressPercentage(bytesReceived, totalBytesToReceive), null) { if (moduleInfo == null) { throw new ArgumentNullException("moduleInfo"); } this.ModuleInfo = moduleInfo; this.BytesReceived = bytesReceived; this.TotalBytesToReceive = totalBytesToReceive; }
public void PostInitialize(ModuleInfo moduleInfo) { if (moduleInfo == null) throw new ArgumentNullException("moduleInfo"); var moduleInstance = moduleInfo.ModuleInstance; try { moduleInstance.PostInitialize(); } catch (Exception ex) { HandleModuleInitializationError(moduleInfo, ex); } }
public void Initialize(ModuleInfo moduleInfo) { if (moduleInfo == null) throw new ArgumentNullException("moduleInfo"); try { var moduleInstance = CreateModule(moduleInfo); moduleInfo.ModuleInstance = moduleInstance; moduleInstance.SetupDatabase(); moduleInstance.Initialize(); } catch (Exception ex) { HandleModuleInitializationError(moduleInfo, ex); } }
/// <summary> /// Uses the container to resolve a new <see cref="IModule"/> by specifying its <see cref="Type"/>. /// </summary> /// <param name="moduleInfo">The module to create.</param> /// <returns>A new instance of the module specified by <paramref name="moduleInfo"/>.</returns> protected virtual IModule CreateModule(ModuleInfo moduleInfo) { if (moduleInfo == null) throw new ArgumentNullException("moduleInfo"); return CreateModule(moduleInfo.ModuleType); }
private void RaiseLoadModuleCompleted(ModuleInfo moduleInfo, Exception error) { this.RaiseLoadModuleCompleted(new LoadModuleCompletedEventArgs(moduleInfo, error)); }
private void InitializeModule(ModuleInfo moduleInfo) { if (moduleInfo.State == ModuleState.Initializing) { this.moduleInitializer.Initialize(moduleInfo); moduleInfo.State = ModuleState.Initialized; this.RaiseLoadModuleCompleted(moduleInfo, null); } }
private IModuleTypeLoader GetTypeLoaderForModule(ModuleInfo moduleInfo) { foreach (IModuleTypeLoader typeLoader in this.ModuleTypeLoaders) { if (typeLoader.CanLoadModuleType(moduleInfo)) { return typeLoader; } } throw new ModuleTypeLoaderNotFoundException(moduleInfo.ModuleName, String.Format(CultureInfo.CurrentCulture, Resources.NoRetrieverCanRetrieveModule, moduleInfo.ModuleName), null); }
private void RaiseModuleDownloadProgressChanged(ModuleInfo moduleInfo, long bytesReceived, long totalBytesToReceive) { this.RaiseModuleDownloadProgressChanged(new ModuleDownloadProgressChangedEventArgs(moduleInfo, bytesReceived, totalBytesToReceive)); }
/// <summary> /// Checks if the module needs to be retrieved before it's initialized. /// </summary> /// <param name="moduleInfo">Module that is being checked if needs retrieval.</param> /// <returns></returns> protected virtual bool ModuleNeedsRetrieval(ModuleInfo moduleInfo) { if (moduleInfo == null) throw new ArgumentNullException("moduleInfo"); if (moduleInfo.State == ModuleState.NotStarted) { // If we can instantiate the type, that means the module's assembly is already loaded into // the AppDomain and we don't need to retrieve it. bool isAvailable = Type.GetType(moduleInfo.ModuleType) != null; if (isAvailable) { moduleInfo.State = ModuleState.ReadyForInitialization; } return !isAvailable; } return false; }
public void PostInitializeModule(ModuleInfo moduleInfo) { if (moduleInfo == null) throw new ArgumentNullException("moduleInfo"); moduleInitializer.PostInitialize(moduleInfo); }
/// <summary> /// Return the list of <see cref="ModuleInfo"/>s that <paramref name="moduleInfo"/> depends on. /// </summary> /// <remarks> /// If the <see cref="ModuleCatalog"/> was not yet validated, this method will call <see cref="Validate"/>. /// </remarks> /// <param name="moduleInfo">The <see cref="ModuleInfo"/> to get the </param> /// <returns>An enumeration of <see cref="ModuleInfo"/> that <paramref name="moduleInfo"/> depends on.</returns> public virtual IEnumerable <ModuleInfo> GetDependentModules(ModuleInfo moduleInfo) { this.EnsureCatalogValidated(); return(this.GetDependentModulesInner(moduleInfo)); }
public void LoadModuleType(ModuleInfo moduleInfo) { if (moduleInfo == null) { throw new System.ArgumentNullException("moduleInfo"); } try { Uri uri = new Uri(moduleInfo.Ref, UriKind.RelativeOrAbsolute); // If this module has already been downloaded, I fire the completed event. if (this.IsSuccessfullyDownloaded(uri)) { this.RaiseLoadModuleCompleted(moduleInfo, null); } else { string path; if (moduleInfo.Ref.StartsWith(RefFilePrefix + "/", StringComparison.Ordinal)) { path = moduleInfo.Ref.Substring(RefFilePrefix.Length + 1); } else { path = moduleInfo.Ref.Substring(RefFilePrefix.Length); } long fileSize = -1L; if (File.Exists(path)) { FileInfo fileInfo = new FileInfo(path); fileSize = fileInfo.Length; } // Although this isn't asynchronous, nor expected to take very long, I raise progress changed for consistency. this.RaiseModuleDownloadProgressChanged(moduleInfo, 0, fileSize); this.assemblyResolver.LoadAssemblyFrom(moduleInfo.Ref); // Although this isn't asynchronous, nor expected to take very long, I raise progress changed for consistency. this.RaiseModuleDownloadProgressChanged(moduleInfo, fileSize, fileSize); // I remember the downloaded URI. this.RecordDownloadSuccess(uri); this.RaiseLoadModuleCompleted(moduleInfo, null); } } catch (Exception ex) { this.RaiseLoadModuleCompleted(moduleInfo, ex); } }
/// <summary> /// Adds a <see cref="ModuleInfo"/> to the <see cref="ModuleCatalog"/>. /// </summary> /// <param name="moduleInfo">The <see cref="ModuleInfo"/> to add.</param> /// <returns>The <see cref="ModuleCatalog"/> for easily adding multiple modules.</returns> public virtual void AddModule(ModuleInfo moduleInfo) { this.Items.Add(moduleInfo); }
protected virtual void HandleModuleTypeLoadingError(ModuleInfo moduleInfo, Exception exception) { if (moduleInfo == null) throw new ArgumentNullException("moduleInfo"); ModuleTypeLoadingException moduleTypeLoadingException = exception as ModuleTypeLoadingException; if (moduleTypeLoadingException == null) { moduleTypeLoadingException = new ModuleTypeLoadingException(moduleInfo.ModuleName, exception.Message, exception); } this.loggerFacade.Error(moduleTypeLoadingException.Message); throw moduleTypeLoadingException; }
private static ModuleInfo CreateModuleInfo(Type type) { string moduleName = type.Name; List<string> dependsOn = new List<string>(); bool onDemand = false; var moduleAttribute = CustomAttributeData.GetCustomAttributes(type).FirstOrDefault( cad => cad.Constructor.DeclaringType.FullName == typeof(ModuleAttribute).FullName); if (moduleAttribute != null) { foreach (CustomAttributeNamedArgument argument in moduleAttribute.NamedArguments) { string argumentName = argument.MemberInfo.Name; switch (argumentName) { case "ModuleName": moduleName = (string) argument.TypedValue.Value; break; case "OnDemand": onDemand = (bool) argument.TypedValue.Value; break; case "StartupLoaded": onDemand = !((bool) argument.TypedValue.Value); break; } } } var moduleDependencyAttributes = CustomAttributeData.GetCustomAttributes(type).Where( cad => cad.Constructor.DeclaringType.FullName == typeof(ModuleDependencyAttribute).FullName); foreach (CustomAttributeData cad in moduleDependencyAttributes) { dependsOn.Add((string) cad.ConstructorArguments[0].Value); } ModuleInfo moduleInfo = new ModuleInfo(moduleName, type.AssemblyQualifiedName) { InitializationMode = onDemand ? InitializationMode.OnDemand : InitializationMode.WhenAvailable, Ref = type.Assembly.CodeBase, }; moduleInfo.DependsOn.AddRange(dependsOn); return moduleInfo; }
private bool AreDependenciesLoaded(ModuleInfo moduleInfo) { IEnumerable<ModuleInfo> requiredModules = this.moduleCatalog.GetDependentModules(moduleInfo); if (requiredModules == null) { return true; } int notReadyRequiredModuleCount = requiredModules.Count(requiredModule => requiredModule.State != ModuleState.Initialized); return notReadyRequiredModuleCount == 0; }
private void BeginRetrievingModule(ModuleInfo moduleInfo) { ModuleInfo moduleInfoToLoadType = moduleInfo; IModuleTypeLoader moduleTypeLoader = this.GetTypeLoaderForModule(moduleInfoToLoadType); moduleInfoToLoadType.State = ModuleState.LoadingTypes; // Delegate += works differently betweem SL and WPF. // We only want to subscribe to each instance once. if (!this.subscribedToModuleTypeLoaders.Contains(moduleTypeLoader)) { moduleTypeLoader.ModuleDownloadProgressChanged += this.IModuleTypeLoader_ModuleDownloadProgressChanged; moduleTypeLoader.LoadModuleCompleted += this.IModuleTypeLoader_LoadModuleCompleted; this.subscribedToModuleTypeLoaders.Add(moduleTypeLoader); } moduleTypeLoader.LoadModuleType(moduleInfo); }
/// <summary> /// Returns the <see cref="ModuleInfo"/> on which the received module dependents on. /// </summary> /// <param name="moduleInfo">Module whose dependant modules are requested.</param> /// <returns>Collection of <see cref="ModuleInfo"/> dependants of <paramref name="moduleInfo"/>.</returns> protected virtual IEnumerable <ModuleInfo> GetDependentModulesInner(ModuleInfo moduleInfo) { return(this.Modules.Where(dependantModule => moduleInfo.DependsOn.Contains(dependantModule.ModuleName))); }