3

ASP.NETが認識していないフォルダーにアセンブリをドロップできるプラグインシステムを作成しようとしています。このプラグインシステムは、ASP.NET MVCベースのアセンブリでは正常に機能しますが、旧式のWebFormアセンブリ(派生クラスのファイル)では.aspx、ファイルを動的アセンブリにコンパイルする必要があります。InheritsSystem.Web.UI.PageSystem.Web.Compilation.BuildManager.aspx

私の問題はBuildManager、プラグインフォルダ内のアセンブリについて何も知らないことであり、それを支援するために私ができることはまったくないようです。私が行った場合:

BuildManager.GetType("PluginAssembly.DefinedType", true, true)

投げます。最初にへの参照を取得してからType試してみる場合:

var instance = BuildManager.CreateInstanceFromVirtualPath(path, type);

typeファイルをコンパイルするために必要な特定のものを渡したにもかかわらず、それでもスローされ.aspxます。BuildManagerファイルをコンパイルするために必要なタイプを見つけるために私ができることはあり.aspxますか?

更新:BuildManager.GetType()実際 に何をしているのかを調べることで、さらに一歩進んだ。タイプが定義されているアセンブリ(「PluginAssembly.DefinedType、PluginAssembly」など)を指定し、System.AppDomain.CurrentDomain.AssemblyResolveイベントにフックすることで、プラグインアセンブリを見つけて返すことができるので、BuildManagerはタイプを正常に構築できます。これにより、フライングカラーで次のように機能します。

BuildManager.GetType("PluginAssembly.DefinedType, PluginAssembly", true, true)

ただし、これはまだ失敗します。

var instance = BuildManager.CreateInstanceFromVirtualPath(path, type);

ファイルのディレクティブ.aspxに同じアセンブリ参照が含まれていますが、次のようになります。Inherits

<%@ Page Language="C#"              
         CodeBehind="Index.aspx.cs"
         Inherits="PluginAssembly.DefinedType, PluginAssembly" %>

私が受け取るエラーは次のとおりです。

「コンパイラエラーメッセージ:CS0234:タイプまたは名前空間の名前'DefinedType'は名前空間'PluginAssembly'に存在しません(アセンブリ参照がありませんか?)」と次のソース出力があります。

Line 205:
Line 206:    [System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
Line 207:    public class plugins_pluginassembly_dll_index_aspx
                 : global::PluginAssembly.DefinedType,
                   System.Web.SessionState.IRequiresSessionState, 
                   System.Web.IHttpHandler {
Line 208:        
Line 209:        private static bool @__initialized;

内部で起こっていることは、私のアセンブリを見つけられないことによってこの例外をスローする責任があるかもしれないBuildManager.CreateInstanceFromVirtualPath()という特定のことを含んでいるようです。System.Web.Util.IWebObjectFactoryこのインターフェースは問題なく実装できますが、それについてわからない場合はどうBuildManagerなりますか?

4

4 に答える 4

1

BuildManagerタイプをロードする方法はわかりませんが、 -イベントをサブスクライブし、アセンブリを自分でロードして、インスタンスを返す(または、認識しない場合は)を使用してみてください。AssemblyResolveAppDomain.CurrentDomain.AssemblyResolveAssemblynull

そのようなコードのすべてがこれと互換性のあるアプローチを使用しているわけではありませんが、試してみる価値があります。

于 2010-04-26T05:17:40.680 に答える
1

ページのコンパイルに使用されるアセンブリを指定する方法は2つあります。

  • BuildManager.AddReferencedAssemblyを呼び出します(ただし、すでにそれを試したと思いますか?)
  • コンパイルページの仮想ディレクトリ構成に必要なアセンブリのリスト(system.web/compilation/assembliesセクション内)を配置し、appdomainでこれらのアセンブリにアクセスできるようにします(フレームワークはAssembly.Loadを使用して構成内のアセンブリを検索するようです)ファイル)。
于 2010-04-23T13:25:25.530 に答える
0

ASP.NET用の遅延読み込みフレームワークを自分で開発しています。プラグインは<@ Assembly>、ページ内のディレクティブをいつでも使用して、アセンブリを手動で参照できます。

于 2012-08-02T18:09:13.057 に答える
0

私は、Webアプリケーション全体を2つの別々のアセンブリに事前コンパイルし、次に適切なアセンブリを掘り下げて、指定されたHTTP要求の正しいものをインスタンス化することにより、 Web配置プロジェクト [1]でこれを解決することになりました。Assembly.GetTypes()Page

プラグイン開発者の負担が大きくなりますが、(セキュリティに敏感で壊れやすい)Webコンテキストで実行する前に、すべてのプラグインをASP.NETコンパイラで完全に検証できるという利点があり、パフォーマンスが向上します。 。

于 2010-04-26T17:08:28.870 に答える