為.Net專案新增動態庫載入路徑_51CTO部落格_linux 動態庫載入路徑
本文分別基於.Net Framework和.Net Core的WPF應用程式為例,來說明如何為.Net專案新增自定義動態庫載入路徑。本文基於.Net Core建立WPF時,使用了.Net5作為目標框架。
1、.Net Framework
在基於.Net Framework的WPF專案中,直接在配置檔案(App.config)中新增runtime節點即可。
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <!-- 指定載入程式集時公共語言執行時搜尋的子目錄, 其中privatePath是相對於*.exe.config檔案的相對路徑, 多個資料夾以分號分隔。--> <probing privatePath="Libs\Lib1;Libs\Lib2"/> </assemblyBinding> </runtime>
2、.Net5
在基於.Net5的WPF專案中,使用privatePath已經不能夠實現指定資料夾程式集的載入了,這大概時因為在.Net5中,程式集的載入依賴於應用程式的.deps.json檔案,而privatePath指定的資料夾中的程式集不會被新增到.deps.json檔案中。
基於<probing privatePath="..." /> doesn't work in .Net 5.0 · Issue #45342 · dotnet/runtime · GitHub,在專案檔案(配置檔案中應該也可以)設定動態庫載入路徑,然後基於AssemblyLoadContext類的Resolving事件,在應用程式查詢未知型別時載入配置檔案中的動態庫。
(1)在.csproj檔案中設定動態庫路徑
<ItemGroup> <RuntimeHostConfigurationOption Include="SubdirectoriesToProbe" Value="Plugins" /> </ItemGroup>
(2)在程式碼中實現型別動態載入
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { //載入程式集事件 AssemblyLoadContext.Default.Resolving += ResolveAssembly; base.OnStartup(e); } //載入指定位置程式集 private static Assembly ResolveAssembly(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName) { var probeSetting = AppContext.GetData("SubdirectoriesToProbe") as string; if (string.IsNullOrEmpty(probeSetting)) { return null; } foreach (var subDirectory in probeSetting.Split(';')) { var pathMaybe = Path.Combine(AppContext.BaseDirectory, subDirectory, $"{assemblyName.Name}.dll"); if (File.Exists(pathMaybe)) { return assemblyLoadContext.LoadFromAssemblyPath(pathMaybe); } } return null; } }