3

動的にコンパイルされたASP.NET Webサイトプロジェクトでは、App_Codeフォルダのアセンブリを明示的に指定できますか?動的にコンパイルされたASP.NET WebサイトのApp_Codeフォルダの明示的なアセンブリ名を指定しますか?

私はASP.NETのWebサイトを実行するとたとえば、通常の状況下でTemporary ASP.NET Files\フォルダに生成されたアセンブリ名が部分的に neizakfoが異なることが一部であるApp_Code.neizakfo.dllのようにランダム化されています。 App_Code_Web1.dllのようなアセンブリの名前を明示的に指定できますか?ビジネス要件によって

明確化

、ウェブサイトは、展開/、プリコンパイルすることはできません。したがって、私は上記のようにTemporary ASP.NET Filesフォルダと動的にコンパイルされたアセンブリのコンテキストで解決策を模索しています。


背景
私は、コンフィギュレーションに保存されているアセンブリ修飾名を使用して、ウェブサイトのApp_Codeフォルダー内のクラスに動的な型のインスタンス化を実行する方法を探しながら、この質問に出くわしたが、インスタンス化ウェブページから、アセンブリの境界を横切る。 Webページとapp_codeコードはデフォルトで2つの異なるアセンブリにコンパイルされるため、現在実行中のアセンブリ(Webページ)またはmscorlibのType名を検索するType.GetType(..)メソッドのデフォルトの動作では、 App_CodeアセンブリからTypeを選択するには十分です。ランダム化されているため、アセンブリ修飾文字列にapp_codeアセンブリ名を含めることはできません。

この問題を解決するために、データ型をクラスライブラリに入れることができます(ただし、これはあらかじめ定義された/正確な名前を持っています)。しかし、私はこの問題を解決するために、その目的のためのクラスライブラリプロジェクトです。

+1

並べ替えhttp://msdn.microsoft.com/en-us/library/bb398860.aspx#PreCompilingToFixedNameAssembliesを参照してください。私はこの動作がはるかによく定義されているので、Webアプリケーションを非常に好む。あなたが探しているのは、Webアプリケーションプロジェクトでは簡単です。 – dash

答えて

4

WebSiteプロジェクトでこれを並べ替えることができます。

プロジェクトをコンパイルするときにMSDN article on using the -fixednames flagがあります。

これにより、各ページ(default.aspx.dll)に対してアセンブリが効果的に作成されます。しかし、ロードするときに探しているコントロールやページの名前を知っておく必要があるため、これはほんのわずかですが、タイプと命名が一貫していることを確認する必要があります。しかし、これはapp_codeのクラス名を尊重すべきです。

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

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

これはWebApplicationプロジェクトでは簡単ではありませんが、あなたはWebSiteプロジェクトに悩まされていると思いますか?

編集:コメントの更新として。パブリッシュWebツールを使用すると、app_codeのすべてのコードが、App_Code.dllというdllディレクトリのbinディレクトリに移動します。固定命名を使用してもこの動作は変わりません(すべての固定命名規則は、各ページ、ユーザーコントロール)。このファイルにILSpyを使用すると、そこで私のクラスを見ることができます。だから私はアセンブリの名前を知っています、そして、それは場所です - 私は最小限の努力でそれの中の型を得ることができるはずです。なぜ私はあなたに別の行動を見ているのだろうか!

私はにApp_Codeに入れ、IDと名前と「人」と呼ばれる単純なクラスを作成し、サイトをコンパイルし、次のコードを実行しました:それは、「人」を出し書い

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というをキャストしようと、私は、次のメッセージが表示されます:

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)); 

、私はその後でした:私は、それは実際にはランダムな名前にApp_Codeを与えた

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

をTemporary ASP.Net Filesで実行してください。

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

+0

私はあなたが示唆したように別個のアセンブリが可能であることを背景情報で指摘しましたが、私がなくてもできるかどうかを試しています。すべてのDLLがWebサイトのbinフォルダにあるわけではありませんので、ASP.NET Tempファイルを列挙するのは躊躇しますが、後で使用するために情報をキャッシュすることは最適化されている可能性があります。あなたの最初の提案では、たとえウェブページがアセンブリ名を知っていても、私は同じ状況のために文字列名でapp_codeクラス(ウェブページではない)を動的にロードできません。固定名提案、app_codeへの影響を理解していない可能性があります。 –

+0

私はちょうど完成のために私の答えを構築していた - 私は別のアセンブリにコードを入れて、このインスタンスでは正しい答えだと思うが、非常にあなたがしようとしていることに興味がある(素晴らしい質問! Webサイトプロジェクトを使用してからしばらくして(私は多くの理由でそれらを嫌いですが)私はそこでこれらの行に沿って何かを試したと確信しているので、私たちの初期のプロジェクトの1つを見て行きます。 – dash

+0

@JohnK私はちょうど試みた実験で私の答えを更新しました。 – dash

関連する問題