4

MEF を使用して、asp.net Web フォーム用のある種のプラグイン システムを作成しようとしています。

これまでのところ、ホスト Web サイトがそのプラグイン フォルダーを検索して、Moduleと呼ばれる他の Web サイトを読み込むソリューションを用意しました。モジュール (プラグイン) は別の Web サイト プロジェクトであるため、 binサブフォルダーに独自のアセンブリがあります。

既にご存じのとおり、ASP.NET アプリケーションはそのbinフォルダーの外にある dll をロードしません。したがって、モジュール ページにアクセスしようとすると (例: plugins/MyModule/Page.aspx )。サーバーがアセンブリMyModuleを読み込めないというエラーが表示されます。モジュールのアセンブリをメインのbinフォルダーに入れると、すべてが機能しますが、すべてのモジュール ファイルを同じフォルダーに保持したいと考えています。

そのため、アセンブリをbinフォルダーの外にロードする方法を探しています。web.config ファイルをいじってみましたが、有効な解決策が見つかりませんでした。

その後、BuildManagerクラスに出くわし、次のコードを書きました。

string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");
foreach (string f in Directory.GetDirectories(pluginPath))
{
    string binPath = Path.Combine(f, "bin");
    if (Directory.Exists(binPath))
    {
        foreach (String file in Directory.GetFiles(binPath, "*.dll"))
        {
            Assembly a = Assembly.LoadFrom(file);
            BuildManager.AddReferencedAssembly(a);
        }
    }
}

プラグインフォルダーでbinフォルダーを含む他のサブフォルダーを検索し、 BuildManagerを使用して対応するアセンブリを読み込みます。このコードを機能させるには、global.aspxアセンブリのPreApplicationStartMethodで呼び出す必要があります。

プラグイン ページ ( plugin/MyModule/Page.aspx ) に移動すると、以前のエラーは表示されませんが、ページは空白です。ソースを確認しましたが、html も何もありません。ページをデバッグしようとしましたが、Page_Loadメソッドが呼び出されません。したがって、Page.aspxの背後にあるコードが呼び出されることはないと思います。

編集:

それで、もう少し検索したところ、解決策が見つかりました:

ページの継承を解決するBuildManager

モジュール アセンブリを読み込むときは、その参照をディクショナリに保存します。次に、AppDomain.CurrentDomain.AssemblyResolveへのイベント ハンドラーで、対応するモジュール アセンブリを返します。

4

1 に答える 1

7

私は同じ問題を抱えています。以下のようにアセンブリを解決して修正しました

protected virtual void Application_Start(object sender, EventArgs e)
    {

        //...

        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }

    System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var currentAssemblies = AppDomain.CurrentDomain.GetAssemblies();

        foreach (var assembly in currentAssemblies)
        {
            if (assembly.FullName == args.Name || assembly.GetName().Name == args.Name)
            {
                return assembly;
            }
        }

        return null;
    }
于 2013-11-18T09:46:51.253 に答える