/// <summary> /// Collate type data from assemblies into an AvailableTypeData object. /// </summary> /// <param name="assemblies">the assemblies to collate data from.</param> /// <param name="typeAccelerators">lookup table of PowerShell type accelerators.</param> /// <returns>an object describing all the available types from the given assemblies.</returns> public static AvailableTypeData AssembleAvailableTypes( IEnumerable <Assembly> assemblies, IDictionary <string, Type> typeAccelerators, out IEnumerable <CompatibilityAnalysisException> errors) { var errAcc = new List <CompatibilityAnalysisException>(); var typeAcceleratorDict = new JsonCaseInsensitiveStringDictionary <TypeAcceleratorData>(typeAccelerators.Count); foreach (KeyValuePair <string, Type> typeAccelerator in typeAccelerators) { var ta = new TypeAcceleratorData() { Assembly = typeAccelerator.Value.Assembly.GetName().Name, Type = typeAccelerator.Value.FullName }; typeAcceleratorDict.Add(typeAccelerator.Key, ta); } var asms = new JsonCaseInsensitiveStringDictionary <AssemblyData>(); foreach (Assembly asm in assemblies) { // Don't want to include this module or assembly in the output if (Assembly.GetCallingAssembly() == asm) { continue; } try { KeyValuePair <string, AssemblyData> asmData = AssembleAssembly(asm); asms.Add(asmData.Key, asmData.Value); } catch (ReflectionTypeLoadException e) { errAcc.Add(new CompatibilityAnalysisException($"Failed to load assembly '{asm.GetName().FullName}'", e)); } } errors = errAcc; return(new AvailableTypeData() { TypeAccelerators = typeAcceleratorDict, Assemblies = asms }); }
/// <summary> /// Collate type data from assemblies into an AvailableTypeData object. /// </summary> /// <param name="assemblies">the assemblies to collate data from.</param> /// <param name="typeAccelerators">lookup table of PowerShell type accelerators.</param> /// <returns>an object describing all the available types from the given assemblies.</returns> public AvailableTypeData AssembleAvailableTypes( IEnumerable <Assembly> assemblies, IReadOnlyDictionary <string, Type> typeAccelerators, out IEnumerable <CompatibilityAnalysisException> errors) { var errAcc = new List <CompatibilityAnalysisException>(); var typeAcceleratorDict = new JsonCaseInsensitiveStringDictionary <TypeAcceleratorData>(typeAccelerators.Count); foreach (KeyValuePair <string, Type> typeAccelerator in typeAccelerators) { var ta = new TypeAcceleratorData() { Assembly = typeAccelerator.Value.Assembly.GetName().Name, Type = typeAccelerator.Value.FullName }; typeAcceleratorDict.Add(typeAccelerator.Key, ta); } var asms = new JsonDictionary <string, AssemblyData>(); foreach (Assembly asm in assemblies) { // Skip over this if (asm == s_executingAssembly || asm.IsDynamic || string.IsNullOrEmpty(asm.Location)) { continue; } if (_excludedAssemblyPathPrefixes != null && IsAssemblyPathExcluded(asm.Location)) { continue; } try { // First check whether an assembly with this name already exists // Only replace it if the current one is newer AssemblyName asmName = asm.GetName(); if (asms.TryGetValue(asmName.Name, out AssemblyData currentAssemblyData) && asmName.Version < currentAssemblyData.AssemblyName.Version) { continue; } KeyValuePair <string, AssemblyData> asmData = AssembleAssembly(asm); try { asms.Add(asmData.Key, asmData.Value); } catch (ArgumentException e) { // We don't have a way in the schema for two assemblies with the same name, so we just keep the first // This is not really valid and we should update the schema to subkey the version errAcc.Add(new CompatibilityAnalysisException($"Found duplicate assemblies with name {asmData.Key}. Kept the first one.", e)); } } catch (Exception e) when(e is ReflectionTypeLoadException || e is FileNotFoundException) { errAcc.Add(new CompatibilityAnalysisException($"Failed to load assembly '{asm.GetName().FullName}'", e)); } } errors = errAcc; return(new AvailableTypeData() { TypeAccelerators = typeAcceleratorDict, Assemblies = asms }); }