摘要:[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
※在此感謝所有的幫助者,感謝~