public IAssembly TryLoad(string dll, string pdb, string version = null)
        {
            if (string.IsNullOrWhiteSpace(dll))
            {
                throw new ArgumentException(nameof(dll));
            }
            if (string.IsNullOrWhiteSpace(pdb))
            {
                throw new ArgumentException(nameof(pdb));
            }

            // Find version if it wasn't provided
            if (string.IsNullOrWhiteSpace(version))
            {
                var assemblyName = _AssemblyNameReader.GetAssemblyName(dll);
                if (assemblyName != null)
                {
                    version = assemblyName.Version.ToString();
                }
            }

            // Used cached assembly if it is already loaded and cached
            IAssembly assembly = _AssemblyCache.FindAlreadyLoadedAssembly(dll, version);

            if (assembly != null)
            {
                return(assembly);
            }

            // Load the assembly
            assembly = _AppDomain.TryLoad(dll, pdb);
            if (assembly == null)
            {
                return(null);
            }

            var assemblyVersion = assembly.GetName()?.Version?.ToString();

            // Cache the loaded assembly (even if it is the wrong version)
            // Also, for threadsafety, get the cached assembly back, in case two threads loaded at the same time
            assembly = _AssemblyCache.Add(dll, assemblyVersion, assembly);

            // Make sure the version matches the requested version
            if (assemblyVersion != version)
            {
                return(null);
            }

            // If configured to do so, load all dependent assemblies immediately,
            if (_Settings.LoadDependenciesProactively)
            {
                var dir = Path.GetDirectoryName(dll);
                if (!dir.EndsWith("bin"))
                {
                    ProactivelyLoadDependencies(Path.Combine(dir, "bin"));
                }
            }

            return(assembly);
        }
示例#2
0
        public IAssembly FindAlreadyLoadedAssembly(string dll, string version = null)
        {
            version = (string.IsNullOrWhiteSpace(version))
                ? _AssemblyNameReader.GetAssemblyName(dll)?.Version?.ToString()
                : version;

            var key = GetKey(dll, version);

            // Find and return already loaded assembly
            if (Assemblies.TryGetValue(key, out IAssembly cachedAssembly))
            {
                _Logger?.WriteLine(PluginLoaderLogLevel.Debug, $"Found already loaded plugin assembly: {key}");
                return(cachedAssembly);
            }

            // See if the Assembly was loaded into the AppDomain already
            // This could happen if it was loaded by some other system or reference
            var alreadyLoddedassemblies = _AppDomain.GetAssemblies();

            if (alreadyLoddedassemblies != null && alreadyLoddedassemblies.Any())
            {
                var dllAssemblyName = _AssemblyNameReader.GetAssemblyName(dll);
                if (dllAssemblyName == null)
                {
                    return(null);
                }
                foreach (var alreadyLoddedassembly in alreadyLoddedassemblies)
                {
                    var loadedAssemblyName = alreadyLoddedassembly.GetName();
                    if (loadedAssemblyName.FullName == dllAssemblyName.FullName && loadedAssemblyName.Version.ToString() == version)
                    {
                        key = GetKey(dll, alreadyLoddedassembly.GetName().Version.ToString());
                        _Logger?.WriteLine(PluginLoaderLogLevel.Debug, $"Loading plugin assembly from dll: {key}");
                        Assemblies.TryAdd(key, alreadyLoddedassembly);
                        return(alreadyLoddedassembly);
                    }
                }
            }

            // No assembly found, return null
            return(null);
        }