/// <summary> /// Finds the and load assemblies. /// </summary> /// <param name="finderParams">The finder parameters.</param> /// <returns>List<Assembly>.</returns> private static List <Assembly> FindAndLoadAssemblies(AssemblyFinderParams finderParams) { if (Directory.Exists(finderParams.Path)) { var files = new DirectoryInfo(finderParams.Path).GetFiles($"*{Constants.DllExtension}", finderParams.SearchOption) .Where(p => p.Name.Contains(finderParams.AssemblyPatternMatch, StringComparison.OrdinalIgnoreCase) && !ExcludedAssemblies.Any(a => p.Name.Contains(a, StringComparison.OrdinalIgnoreCase))).OrderBy(p => p.Name).ToList(); var assemblies = new List <Assembly>(); var assemblyNames = new List <AssemblyName>(); foreach (var item in files) { assemblyNames.Add(new AssemblyName(Path.GetFileNameWithoutExtension(item.Name))); } foreach (var item in files) { if (!AssemblyLoadContext.Default.Assemblies.Any(p => p.GetName().Name.Equals(Path.GetFileNameWithoutExtension(item.Name), StringComparison.OrdinalIgnoreCase))) { var context = new SharedLoadContext(item.FullName); context.AddSharedAssembly(assemblyNames.ToArray()); var assembly = context.LoadMainAssembly(); assemblies.Add(assembly); } else { var assembly = AssemblyLoadContext.Default.Assemblies.FirstOrDefault(p => p.GetName().Name.Equals(Path.GetFileNameWithoutExtension(item.Name), StringComparison.OrdinalIgnoreCase)); assemblies.Add(assembly); } } return(assemblies); } return(new List <Assembly>()); }
/// <summary> /// Validates the assemblies. /// </summary> /// <param name="assemblies">The assemblies.</param> /// <param name="finderParams">The finder parameters.</param> /// <exception cref="InvalidOperationException">Assembly {assembly.FullName} does not belong to {finderParams.Path}, application execution has been stopped due to security reasons.</exception> private static void ValidateAssemblies(IEnumerable <Assembly> assemblies, AssemblyFinderParams finderParams) { var thisAssembly = Assembly.GetExecutingAssembly(); var thisAssemblyKey = Shared.ResourceReader.GetEmbeddedResource(finderParams.EmbededResourceKey, thisAssembly); var thisStrongName = Readers.ResourceReader.GetStrongName(thisAssemblyKey, thisAssembly); foreach (var assembly in assemblies) { var key = Readers.ResourceReader.GetPublicKey(assembly); var strongName = Readers.ResourceReader.GetStrongName(key, assembly); if (!strongName.PublicKey.Equals(thisStrongName.PublicKey)) { throw new InvalidOperationException($"Assembly {assembly.FullName} does not belong to {finderParams.Path}, application execution has been stopped due to security reasons."); } } }
/// <summary> /// Finds the specified finder parameters. /// </summary> /// <param name="finderParams">The finder parameters.</param> /// <returns>IEnumerable<Assembly>.</returns> public static IEnumerable <Assembly> Find(AssemblyFinderParams finderParams) { var assemblies = FindAndLoadAssemblies(finderParams); ValidateAssemblies(assemblies, finderParams); var infos = new List <ModuleInfo>(); foreach (var item in assemblies) { infos.Add(GetModuleInfo(item)); } var sorted = SortDependencies(infos); return(sorted.Select(p => p.Assembly)); }