예제 #1
0
        private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            Assembly result;

            if (_cache.TryGetValue(args.Name, out result))
            {
                return(result);
            }

            var pattern     = @"^(?<name>[^,]+),[ ]*Version=(?<version>[^,]+)(,[ ]*Culture=(?<culture>[^,]+))?(,[ ]*PublicKeyToken=(?<token>[^,]+))?$";
            var matchResult = Regex.Match(args.Name, pattern);

            if (!matchResult.Success)
            {
                return(null);
            }

            var     assemblyName = matchResult.Groups["name"].Value;
            Version assemblyVersion;

            Version.TryParse(matchResult.Groups["version"].Value, out assemblyVersion);

            var expectedAssemblyDirectory = Path.Combine(_temporaryDirectory, assemblyName).EnsureSlash();
            var expectedAssemblyPath      = Path.Combine(expectedAssemblyDirectory, assemblyVersion.ToString(), assemblyName + ".dll");

            string resolvedPath = null;

            if (File.Exists(expectedAssemblyPath))
            {
                resolvedPath = expectedAssemblyPath;
            }
            else
            {
                foreach (var directory in _directoriesToScan)
                {
                    var possibleAssemblyPath = Path.Combine(directory, assemblyName + ".dll");
                    if (!File.Exists(possibleAssemblyPath))
                    {
                        continue;
                    }

                    CacheAssembly(possibleAssemblyPath);
                }
            }

            if (File.Exists(expectedAssemblyPath))
            {
                resolvedPath = expectedAssemblyPath;
            }
            else
            {
                var versions = IOExtensions.SearchDirectories(expectedAssemblyDirectory + "\\*")
                               .Items
                               .Select(d =>
                {
                    d = d.TrimEnd('\\');
                    Version v;
                    Version.TryParse(d.Substring(d.LastIndexOf('\\') + 1), out v);
                    return(v);
                })
                               .Where(v => v != null)
                               .OrderByDescending(r => r).ToList();

                if (versions.Any())
                {
                    resolvedPath = Path.Combine(expectedAssemblyDirectory, versions.First().ToString(), assemblyName + ".dll");
                }
            }

            if (string.IsNullOrWhiteSpace(resolvedPath))
            {
                _logger.Warn($"# Assembly {args.Name} not resolved");
                _cache.TryAdd(args.Name, null);
                return(null);
            }

            _logger.Info($"# Assembly {args.Name} resolved with {resolvedPath}");

            result = Assembly.LoadFile(resolvedPath);
            _cache.TryAdd(args.Name, result);

            return(result);
        }