モジュール式の ASP.NET アプリケーションを作成したいと考えています。たとえば、ある種のモジュールローダーであるメインアプリケーションがあります。「Default.aspx」ページは 1 つだけです。そして、ロードされたモジュールに基づいて、このページはメニューとモジュール内のページへのリンクを作成します。
モジュールをdllにパックされたASP.NETプロジェクトにしたい。そのため、その dll をメイン アプリケーションの "Modules" フォルダーにドロップすると、モジュールが識別され、リフレクションを使用してモジュールが読み込まれ、それらを調べてページが見つかり、そこからメニューが作成されます。
私がこれまでに行ったこと:
私のソリューションには、「DummyModule」プロジェクトがあります。このプロジェクトは 3 ページしかありません。それについて特別なことは何もありません。
そして、「MainApp」という別のプロジェクトがあります。ここが「大当たり」です。
このプロジェクトには、「ModuleLoader」クラスがあります。「LoadModules」メソッドが呼び出されると、アプリケーションの「Modules」フォルダーで「dll」ファイルが検索されます。そして、リフレクションを使用して、これらのモジュールをロードします。これらのモジュールのそれぞれについて、引き続きリフレクションを使用して、すべての「ページ」タイプを検索し、名前をリストに格納します。
「Default.aspx」ページの「Page_Load」メソッドで、「ModuleLoader」クラスを呼び出し、すべてのモジュール名と各モジュールのすべてのページ名を取得し、そこからメニューを構築します。適切なページをロードするために必要なすべての情報を含むハイパーリンク パターンを作成しました。つまり、「/ModuleName/PageName」です。「aspx」拡張機能は使用していません。OK、これまでのところ、とても良いです。
ここがトリッキーな部分です。
「PageLoaderModule」という HTTPModule を作成しました。このモジュールはすべてのリクエストをインターセプトするため、URL を読み取って、ロードする必要があるモジュールからページを特定できます。
そして、それはまさに私ができないことであり、これを解決する方法がわかりません。
私がやっていること:
public class PageLoaderModule : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
//clean-up code here.
}
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
}
private void context_BeginRequest(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
if (Regex.IsMatch(application.Request.RawUrl, @"/.+/.+"))
{
var parts = application.Request.RawUrl.Split('/').Where(u => !string.IsNullOrWhiteSpace(u)).ToList();
IHttpHandler page = ModuleManager.GetPage(parts[0], parts[1]);
page.ProcessRequest(application.Context);
}
}
#endregion IHttpModule Members
}
「GetPage」メソッドは、指定されたアセンブリで正しい「Page」タイプを見つけ、インスタンスを作成して、その Page インスタンスを返します。
しかし、IHTTPHandler インターフェイスの「ProcessRequest」メソッドを呼び出すと、ページが読み込まれません。
それは可能ですか?何かご意見は?
編集:
@Slavo の提案を試しました。
anwser を検索しているときに、同様のソリューションを見つけて試し、独自の VirtualPathProvider と VirtualFile を実装しました。それはほとんどうまくいきました。仮想パスは正しいページを処理してロードしますが、ページがロードされると、ブラウザで次のエラーが発生しました。
Parser Error Message: Could not load type 'DummyModule.Pages.DummyPage3'.
Source Error:
Line 1: <% @ Page Language="C#" AutoEventWireup="true" CodeBehind="DummyPage3.aspx.cs" Inherits="DummyModule.Pages.DummyPage3" %>
だから、何か間違ったことをしたのか、それとも私が探している解決策ではないのかわかりません。だから、私は他のオプションを試しました。
「.aspx」ファイルの「ビルド アクション」を「埋め込みリソース」として正しくマークしたので、仮想パスとしてアクセスできます。しかし、それでも上記のエラーが発生しました。