摘要:[C#] Load DLL(Assembly) from a specific folder (.net dll)
使用說明:
1.在使用前請先透過'加入參考'加入 System.Configuration 組件。
2.在 App.config 加入下列,並設定自訂 DLL 資料夾的路徑。
<configuration>
  <appSettings>
    <add key="DllPrivatePath" value="myDLLFolder1;myDLLFolder2/myDLLFolder22;myDLLFolder3"/>
  </appSettings>
</configuration>
3.在主程式類別(Program Class)手動加入'靜態建構函式',並在該函式裡面'加入下段程式碼'。
class Program
{
    /// <summary>
    /// 加入此段程式碼
    /// </summary>
    static Program()
    {
        LoadAssemblys.LoadAssembly.AddAssemblyPrivatePath();
    }
    static void Main(string[] args)
    {
        //That new Private Path DLL Assembly class ....
    }
}
LoadAssembly 類別的原始碼:
using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
namespace LoadAssemblys
{
    internal static class LoadAssembly
    {
        private readonly static object _regAddAssemblyPrivatePathLock = new object();
        /// <summary>
        /// 是否已設定(掛載)過解析'自訂 DLL 資料夾'功能
        /// </summary>
        private static bool _hasRegAddAssemblyPrivatePath = false;
        /// <summary>
        /// 設定(掛載)能解析'自訂 DLL 資料夾'內的 DLL 組件功能
        /// </summary>
        public static void AddAssemblyPrivatePath()
        {
            if (_hasRegAddAssemblyPrivatePath)
            {
                return;
            }
            lock (_regAddAssemblyPrivatePathLock)
            {
                if (!_hasRegAddAssemblyPrivatePath)
                {
                    AppDomain.CurrentDomain.AssemblyResolve += AssemblyPrivatePath;
                    _hasRegAddAssemblyPrivatePath = true;
                }
            }
        }
        /// <summary>
        /// 解析'自訂 DLL 資料夾'內的 DLL 組件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <returns>回傳所需的 DLL 組件</returns>
        private static Assembly AssemblyPrivatePath(object sender, ResolveEventArgs args)
        {
            var addedAssmbs = AppDomain.CurrentDomain.GetAssemblies();
            var someAssmb = addedAssmbs.FirstOrDefault(x => x.FullName == args.Name);
            if (someAssmb != null)
            {
                return someAssmb;
            }
            var assmbPaths = _dllPrivatePath.Value;
            if (!assmbPaths.Any())
            {
                return null;
            }
            var assmbName = new AssemblyName(args.Name).Name;
            Assembly executingAssemblies = Assembly.GetExecutingAssembly();
            AssemblyName[] referencedAssmbNames = executingAssemblies.GetReferencedAssemblies();
            foreach (AssemblyName refAssmbName in referencedAssmbNames)
            {
                if (new AssemblyName(refAssmbName.Name).Name == assmbName)
                {
                    foreach (var path in assmbPaths)
                    {
                        var dllFullPath = Path.Combine(path, assmbName + ".dll");
                        if (File.Exists(dllFullPath))
                        {
                            return Assembly.LoadFrom(dllFullPath);
                        }
                    }
                }
            }
            return null;
        }
        /// <summary>
        /// 取得'自訂 DLL 資料夾'路徑
        /// </summary>
        private readonly static Lazy<string[]> _dllPrivatePath = new Lazy<string[]>(DllPrivatePathCore);
        /// <summary>
        /// 解析 App.config 裡 AppSettings 資料的 DllPrivatePath 值(路徑)
        /// </summary>
        /// <returns>解析後的值(路徑)</returns>
        private static string[] DllPrivatePathCore()
        {
            var appDir = AppDomain.CurrentDomain.BaseDirectory;
            var dllPrivatePath = ConfigurationManager.AppSettings["DllPrivatePath"];
            if (!string.IsNullOrEmpty(dllPrivatePath) && !string.IsNullOrEmpty(appDir))
            {
                return dllPrivatePath.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                                     .Select(x => Path.Combine(appDir, x.TrimEnd('\\', '/')) + @"\")
                                     .ToArray();
            }
            return new string[0];
        }
    }
}
主要參考:
AppDomain.AssemblyResolve Event Tips
C# - Load Assembly from Specific Directory Path
※在此感謝所有的幫助者,感謝~