ASP.NET Core 2.2でのプラグイン化開発の改善
3182 ワード
筆者はAsp.Net MVCプラグイン化開発の簡略化方案に基づいて研究した.NET FrameworkのASP.NETプラグイン化の開発後、ASP.NET Core 2.0でのプラグイン化開発においてASPに基づく研究を行った.NET Core 2.0のプラグイン化開発、およびASP.NET Core 2.0ではRazor Pageに基づくプラグイン化が開発されている.しかし最近はNET Core 2.1のプラグイン化開発で新たな問題が発生しました.
ASP.NET Core 2.1は、ビューをダイナミックライブラリにコンパイルし、
2.0バージョンのように
筆者は大量の資料を調べた後、やっと問題の根源を見つけた:
しかし,プラグイン化フレームワークでは,プラットフォームとプラグインをデカップリングするために,プラグインAssemblyは動的に検索してロードされ,直接ハードコードを書くことはできない.これは、以前のブログでも述べたように、
関連コードGitee:aspnet-mvc-plugin-sample/asp.net_core_22
ASP.NET Core 2.1は、ビューをダイナミックライブラリにコンパイルし、
proj.views.dll
のようなダイナミックライブラリを生成することができ、パブリッシュ時にViews
ディレクトリをパブリッシュする必要はありません.しかし、上記のプラグイン化方法を使用すると、.views.dll
がターゲットディレクトリに正しくコピーされていても、Shadow CopyおよびAssemblyロードに問題がない場合でも、実行時にViews
ディレクトリの下でビューファイルを検索する必要があります.2.0バージョンのように
Views
ディレクトリをコピーして正常に動作する効果はありますが、.dll
すべてをコピーすれば解決できる問題である以上、誰がもう1つのViews
をコピーしたいですか?筆者は大量の資料を調べた後、やっと問題の根源を見つけた:
.views.dll
はデフォルトのロード方式を採用することができず、CompiledRazorAssemblyApplicationPartFactory
を使用してロードしなければならない.CompiledRazorAssemblyApplicationPartFactory
は、AssebmlyをApplicationPart
にロードし、ApplicationPartManager
に追加することができる.したがって、IMvcBuilder.ConfigureApplicationPartManager()
で処理を構成する必要がある(Stack Overflow上のASP.NET Core MVC 2.1 mvc Views in plugin参照)しかし,プラグイン化フレームワークでは,プラットフォームとプラグインをデカップリングするために,プラグインAssemblyは動的に検索してロードされ,直接ハードコードを書くことはできない.これは、以前のブログでも述べたように、
Startup
のConfigure()
とConfigureServices()
を組み合わせて、mvcBuilder
のメンバー変数で処理する必要があります.ロードはLoadPlugins()
で実行されます(ASP.NET Core 2.0でのプラグイン化開発参照).ConfigureApplicationPartManager()
もLoadPlugins()
に移動する必要があります.private void LoadPlugins(IHostringEnvironment env)
{
// Shadow Copy
// ......
// dll `.views.dll`
// Shadow Copy Assembly Mvc
var groups = Directory.EnumerateFiles(target, "*.dll")
.GroupBy(path => path.EndsWith(".views.dll", StringComparison.OrdinalIgnoreCase))
.ToDictionary(group => group.Key);
// .views.dll ApplicationPart
groups[false]
.Select(AssemblyLoadContext.Default.LoadFromAssemblyPath)
.ForEach(mvcBuilder.AddApplicationPart);
// .views.dll CompiledRazorAssemblyApplicationPartFactory
mvcBuilder.ConfigureApplicationPartManager(manager =>
{
var razorPartFactory = new CompiledRazorAssemblyApplicationPartFactory();
groups[true]
.Select(AssemblyLoadContext.Default.LoadFromAssemblyPath)
.SelectMany(assembly => razorPartFactory.GetApplicationParts(assembly))
.ForEach(manager.ApplicationParts.Add);
});
}
関連コードGitee:aspnet-mvc-plugin-sample/asp.net_core_22