実験コード
ClassLibrary1.csprojというdllのプロジェクト
dllに作成したクラス。(中身に特に意味はない)
namespace ClassLibrary1; public class Class1 { public static Class1 CreateInstance() => new Class1(); public int Data1; public int Data2; }
winui3のアプリプロジェクト
メイン画面側で、動的に👆のdllを呼んで、その中のクラスのインスタンスを持つようにした。
(「data 」に入れたものが、「ClassLibrary1.Class1」クラスのインスタンス)
で、そのインスタンスを、画面(Page)遷移時のパラメータとして、contentFrame.Navigate()
の第二引数に渡した。
using Microsoft.UI.Xaml.Media.Animation; using System; using System.Reflection; namespace FileVerUpTool; public sealed partial class MainWindow : Window { public MainWindow() => this.InitializeComponent(); private void nvSample_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args) { var dll = Assembly.LoadFile(@"C:\git\FileVerUpTool\ClassLibrary1\bin\x64\Debug\net6.0\ClassLibrary1.dll"); var type = dll.GetType("ClassLibrary1.Class1"); var obj = Activator.CreateInstance(type); var method = type.GetMethod("CreateInstance", BindingFlags.Static | BindingFlags.Public); var data = method.Invoke(obj, null); if (args.SelectedItemContainer != null) { if ((string)args.SelectedItemContainer?.Tag == "SamplePage1") { contentFrame.Navigate(typeof(BlankPage1), (ClassLibrary1.Class1)data, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight }); } } } }
で、ページの中のOnNavigatedTo()
で、👆で渡したインスタンスを受けるのだが、その際にClassLibrary1.Class1
でキャストして受けると、
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Navigation; namespace FileVerUpTool; public sealed partial class BlankPage1 : Page { public BlankPage1() => this.InitializeComponent(); protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); var a = (ClassLibrary1.Class1)e.Parameter; } }
こんな感じの例外が起きる。
これが、なんでおきるのかさっぱりわからなかった。
原因
ここに書かれていた。
最初、NavigationViewの「Navigate()」メソッドのパラメータが怪しい?とか思ってたが、そこは関係なかった。
対策
Assembly.LoadFile()
の代わりに、Assembly.LoadFrom()
でdllをロードする。
dllのロード動作
Assembly.LoadFile()
使用時の、出力欄のモジュール読み込みメッセージはコレ。
1回目も2回目も、両方「シンボルが読み込まれました」となっている。
Assembly.LoadFrom()
使用時の、出力欄のモジュール読み込みメッセージはコレ。
どうやら、LoadFrom()のときは、同じdllを2回目によんだときに、アンロードしている様子。
(LoadFileのときは、アンロードは行われず、「シンボルが読み込まれました」となっている)
参考?
アセンブリの読み込みのベスト プラクティス
1 つのアセンブリを複数のコンテキストに読み込まない
Assembly.LoadFile()
は、別のpathに置かれた同じdllを読むけど、
Assembly.LoadFrom()
は、それを読まない、と書いてるっぽい。
Difference between LoadFile and LoadFrom with .NET Assemblies?
👆のMSdocsが何かいてるかわからん!という記事。同意...