私はいくつかのリードを得るために同様の問題を見つけるのに本当に苦労しましたが、私たちが抱えているケースについて誰も説明していないようです.
バックグラウンド
次の一般的な設計の製品があります。
【ローカルインストールフォルダ】
- 製品機能の大部分を実装する .NET アセンブリのセットが含まれています。
- 例:実装 1.dll、実装 2.dll
【GAC】
- ClientAPI.dll。エンド ユーザーの Visual Studio プロジェクトから参照されるクライアント アセンブリ。ローカル インストール フォルダー内の実装 dll への強力な参照があります。
ClientAPI.dll には、エンド ユーザー プロジェクトを呼び出す必要があるエントリポイントがあります。と呼びましょうInitialize()
。
最初に行うことは、イベントを使用して、Initialize
いわゆるアセンブリ解決ハンドラーを現在のドメインにインストールすることです。AssemblyResolve
このハンドラーは、.dll を使用して、実装 dll を見つけてクライアント プロセスにロードする方法を認識しますAssembly.Load()
。
コンソール アプリケーションを考えてみましょう。次のようになります。
class Class1
{
void Main(string[] args)
{
ClientAPI.Initialize();
// Use other API's in the assembly, possibly internally referencing the
// implementation classes, that now will be resolved by our assembly
// resolve handler.
}
}
これで、コンソール/Windows フォーム/WPF の世界ですべてがうまくいきました。アセンブリ解決ハンドラーが適切にインストールされて呼び出され、ClientAPI.dll が機能を要求すると、実装 DLL への参照を正常に解決できます。
問題文
そうは言っても、コンソールまたは WPF アプリケーションのみをサポートするつもりはないため、ASP.NET で同じ設計に依存していました。したがって、VS 2010 で新しい ASP.NET Web アプリケーション プロジェクトを作成すると、すべてが次のように簡単になると考えました。
class Globals : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
ClientAPI.Initialize();
// ...
}
}
ASP.NET ランタイム ユニバースに 20 ~ 30 時間滞在し、開発サーバーと IIS の両方で上記のことを試してみると、実際には期待どおりではないことがわかりました。
ASP.NET では、ClientAPI
クラスがどこかで参照されるとすぐに、他のアセンブリへのすべての参照が即座に解決されることがわかります。それだけではありません。結果はキャッシュされます (.NET 2.0 以降は設計によるものです)。これは、CLR を支援しようとする機会がまったくないことを意味します。
私たちが試して学んださまざまなことについて詳しく説明することなく、基本的に次の質問に行き着きます。
ASP.NET がこのような参照を解決するのはなぜですか? 他のタイプのアプリケーションが行う方法とは互換性がありません。さらに、外部タイプ/アセンブリへの参照が最初に必要になったときに解決されるように指定されている.NET / CLRランタイムのドキュメントに従っていません(つまり、コードで最初に使用されます)。
どんな種類の洞察/アイデアも高く評価されます!