3

In a dynamically compiled ASP.NET Website project, can the assembly for the App_Code folder be explicitly named?

For example, under regular circumstances when I run an ASP.NET website the assembly name generated into the Temporary ASP.NET Files\ folder is partially randomized like App_Code.neizakfo.dll where neizakfo is the portion that can differ. Can I explicitly provide a name for the assembly like App_Code_Web1.dll?

Clarification

By business requirements, the website cannot be precompiled/deployed. Therefore I'm seeking a solution in context of the Temporary ASP.NET Files folder and dynamically compiled assemblies as noted above.


Background:
I came across this question while looking for a way to perform dynamic type instantiation on a class in the App_Code folder of a website using an assembly-qualified name stored in configuration, but instantiated from the web page, thus crossing an assembly boundary. Because the web page and app_code code are compiled into two different assemblies by default, the Type.GetType(..) method's default behaviour of searching for the Type name either in the current executing assembly (the web page) or in mscorlib doesn't suffice for picking any Type from the App_Code assembly. Being randomized, the app_code assembly name is not known for me to include in the assembly-qualified string.

I can put the data Type in a class library (because that does have an predefined/exact name) to get rid of this problem, however I'd like to know how to do this inside the website itself without creating a class library project for the purpose.

4

1 に答える 1

4

これは、WebSiteプロジェクトで行うことができます。

プロジェクトのコンパイル時に-fixednamesフラグを使用することに関するMSDNの記事があります。

これにより、各ページのアセンブリ(default.aspx.dll)が効果的に作成されます。ただし、ロード時に探しているコントロールまたはページの名前を知る必要があるため、これはほんの少しだけ便利です。したがって、タイプと名前の一貫性を確保する必要があります。ただし、これが機能するように、app_codeのクラスの名前を尊重する必要があります。

もう1つできることは、app_code内のすべてのコードを独自のアセンブリに移動し、それをプロジェクト参照として追加することです。それはまたこの問題を単純化するでしょう。

最後に、binディレクトリ内のすべてのdllを列挙し、探しているタイプをそれぞれで検索できます。これはかなり費用がかかるので、一度実行し、結果をどこかにキャッシュして、そのタイプを検索するたびに実行し続けないようにします。これはおそらく最悪の解決策です。

これはWebApplicationプロジェクトで行うのは簡単ですが、WebSiteプロジェクトで立ち往生していると思いますか?

編集:コメントの更新として; 公開Webツールを使用する場合、app_code内のすべてのコードはApp_Code.dllというdllのbinディレクトリに配置されます-固定命名を使用しても、この動作は変わりません(すべての固定命名はdllの命名に影響します各ページ、usercontrol)。このファイルでILSpyを使用すると、そこにクラスが表示されます。だから私はアセンブリの名前とその場所を知っています-最小限の労力でその中のタイプを取得できるはずです。なぜ私はあなたとは異なる行動を見ているのだろうか!

IDと名前を使用して「Person」という単純なクラスを作成し、それをApp_Codeに配置してサイトをコンパイルし、次のコードを実行しました。

  Type myType = Assembly.LoadFrom(Server.MapPath("~/bin/App_Code.dll")).GetType("Person", true);
  Response.Write(myType.ToString());

さすがに「人」と書いてありました。

さらに編集

ペニードロップ!私がそうするなら:

  object myObject= Activator.CreateInstance("App_Code.dll", "Person");

そして、myObjectをpersonにキャストしようとすると、次のメッセージが表示されます。

The type 'Person' exists in both 'App_Code.dll' and 'App_Code.jydjsaaa.dll'

ですから、悪意を持って行動する時が来ました。

Global.asaxのApplication_OnStartで、次の手順を実行します。

Application["App_Code_Assembly"] = Assembly.GetAssembly(typeof(Person));

テストのデフォルトページで、次のことを行いました。

  Assembly app_Code = Application["App_Code_Assembly"] as Assembly;
  Response.Write(app_Code.FullName);

これにより、一時ASP.Netファイルで実際に実行されているランダムな名前のapp_codeが得られました。

これが私がWebサイトプロジェクトを嫌う理由です;-)

于 2012-03-01T17:16:10.380 に答える