WPF Prism 複数フォルダから動的にモジュールを読み込む方法(単一ファイル)

実現したいこと

「Modules」と「Plugins」というフォルダがあり、それぞれのフォルダに配置されているモジュールを動的に読み込みし、単一ファイルでアプリケーションを発行したいです。(「Modules」は遅延読み込み、「Plugins」は起動時に読み込み)

前提

アプリケーション本体と、複数のモジュールで構成されているアプリケーションをPrismで作成しております。

「Modules」には50個ほどのプロジェクトがあり、こちらは呼び出し時にロードされる遅延読み込みをしております。(Prism.Modularity.InitializationMode.OnDemand)

「Plugins」には機能拡張用の便利ツール等の独立したプロジェクトを配置し、アプリケーション起動時に読み込みされ、Menu要素に表示しております。(Prism.Modularity.InitializationMode.WhenAvailable)

どちらのモジュールも要件によって動的に配置され、アプリケーション本体は何のモジュールがあるかを知りません。

発生している問題・エラーメッセージ

上記の動作は、以下のサイトを参考にして、通常のアプリケーションの発行方法では実現できております。
Multiple DirectoryModuleCatalog in a Prism application(stack overflow)

App.xaml.cs

1protected override IModuleCatalog CreateModuleCatalog() 2{ 3 var path = Path.GetDirectoryName(AppContext.BaseDirectory); 4 var directories = new string[] { "Modules", "Plugins" }; 5 List<IModuleCatalogItem> components = []; 6 var catalog = new ModuleCatalog(); 7 8 foreach (var dir in directories) 9 { 10 var dirCatalog = new DirectoryModuleCatalog() { ModulePath = $"{path}\\{dir}" }; 11 dirCatalog.Initialize(); // ★単一ファイルで発行した場合、ここでエラーが発生 12 components.AddRange(dirCatalog.Items); 13 } 14 foreach (var component in components) 15 { 16 catalog.Items.Add(component); 17 } 18 // 呼び出し時にモジュールを読み込む(遅延読み込み) 19 foreach (var moduleInfo in catalog.Modules) 20 { 21 if (Path.GetFileName(Path.GetDirectoryName(moduleInfo.Ref)) == "Modules") 22 moduleInfo.InitializationMode = InitializationMode.OnDemand; 23 } 24 return catalog; 25}

しかし、単一ファイルで発行した場合には、上記エラー発生個所のPrism内部で、.NET非互換性APIのAssembly.Location等が使用されており、Pathが空文字になるためエラーが発生しているように見受けられます。

DirectoryModuleCatalog.netcore.cs
[Prism.Modularity]

DirectoryModuleCatalog.netcore.cs

1/// <summary> 2/// Drives the main logic of building the child domain and searching for the assemblies. 3/// </summary> 4protected override void InnerLoad() 5{ 6 if (string.IsNullOrEmpty(this.ModulePath)) 7 throw new InvalidOperationException(Resources.ModulePathCannotBeNullOrEmpty); 8 9 if (!Directory.Exists(this.ModulePath)) 10 throw new InvalidOperationException( 11 string.Format(CultureInfo.CurrentCulture, Resources.DirectoryNotFound, this.ModulePath)); 12 13 AppDomain childDomain = AppDomain.CurrentDomain; 14 15 try 16 { 17 List<string> loadedAssemblies = new List<string>(); 18 19 var assemblies = ( 20 from Assembly assembly in AppDomain.CurrentDomain.GetAssemblies() 21 where !(assembly is System.Reflection.Emit.AssemblyBuilder) 22 && assembly.GetType().FullName != "System.Reflection.Emit.InternalAssemblyBuilder" 23 && !String.IsNullOrEmpty(assembly.Location) 24 select assembly.Location 25 ); 26 27 loadedAssemblies.AddRange(assemblies); 28 29 Type loaderType = typeof(InnerModuleInfoLoader); 30 31 if (loaderType.Assembly != null) 32 { 33 var loader = 34 (InnerModuleInfoLoader) 35 childDomain.CreateInstanceFrom(loaderType.Assembly.Location, loaderType.FullName).Unwrap(); 36 37 this.Items.AddRange(loader.GetModuleInfos(this.ModulePath)); 38 } 39 } 40 catch (Exception ex) 41 { 42 throw new Exception("There was an error loading assemblies.", ex); 43 } 44}

エラーメッセージ

There was an error loading assemblies.

同じような処理をされている方もいらっしゃるかと思いますので、どのような方法を取っていらっしゃるのか、お力添えいただけると幸いです。
よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

Visual Studio 2022 Version 17.8.6
.NET 8
Prism.DryIoc (8.1.97)

なお、平日日中のお返事になりますことをご了承ください。

コメントを投稿

0 コメント