2012-02-11 8 views
4

私のASP.NET MVCアプリケーションでは、小さなヘルパーを使用してすべてのコントローラを反復処理しています。 このヘルパーは、私のMVCアプリケーションとは別のアセンブリにあり、参照しています。Assembly.GetCallingAssembly()を使用して呼び出しアセンブリを返しません

ヘルパーでAssembly.GetCallingAssembly()メソッドを呼び出すと、MVCアプリケーションアセンブリが返されませんが、代わりにヘルパーアセンブリが返されるという問題があります。これは、すべてが私のコントローラはMVCアプリのアセンブリで暮らしており、私はそれを反映する必要があります。

マイコード:

**The view code(MVC app assembly):** 
<nav> 
    <ul id="menu"> 
     @foreach(var item in new MvcHelper().GetControllerNames()) 
     { 
     @Html.ActionMenuItem(
       (string)HttpContext.GetGlobalResourceObject("StringsResourse", item), "Index", 
       item) 
     } 
    </ul> 
</nav> 

**The Helper code(independent assembly):** 

public class MvcHelper 
{ 
    public List<string> GetControllerNames() 
    { 
     var controllerNames = new List<string>(); 
     GetSubClasses<Controller>().ForEach(
      type => controllerNames.Add(type.Name)); 
     return controllerNames; 
    } 

    private static List<Type> GetSubClasses<T>() 
    { 
     return Assembly.GetCallingAssembly().GetTypes().Where(
      type => type.IsSubclassOf(typeof(T))).ToList(); 
    } 
} 

私はここで間違って何をしているのですか? GetCallingAssembly MSDN docsから

答えて

14

私はここで間違っていますか?

何もありません。 RazorビューがASP.NETランタイムによって別々のアセンブリとしてコンパイルされているという事実はおそらく分かりません。これらのアセンブリは動的です。彼らはあなたのASP.NET MVCアプリケーションアセンブリとは関係ありません。あなたはすべての参照されるアセンブリを介してすべてのコントローラ理由だけではなくループを取得し、コントローラからの派生タイプを検索したい場合は

App_Web_fqxdopd5, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 

:あなたはあなたのビューでヘルパーを呼び出しているのでAssembly.GetCallingAssembly()方法は、このようなものを返すのだろうか?これにはAppDomain.CurrentDomain.GetAssemblies()メソッドを使用できます。そして、各アセンブリ時にちょうどGetTypes()とフィルタのために: - あなたのMvcHelperモジュール(およびアセンブリ)内にあるGetSubClassesを呼び出すメソッドではなく、MVCアプリ自体を

public class MvcHelper 
{ 
    private static List<Type> GetSubClasses<T>() 
    { 
     return AppDomain 
      .CurrentDomain 
      .GetAssemblies() 
      .SelectMany(
       a => a.GetTypes().Where(type => type.IsSubclassOf(typeof(T))) 
      ).ToList(); 
    } 

    public List<string> GetControllerNames() 
    { 
     var controllerNames = new List<string>(); 
     GetSubClasses<Controller>().ForEach(
      type => controllerNames.Add(type.Name)); 
     return controllerNames; 
    } 
} 
+0

+1良い選択肢を提案します。 –

0

は、現在実行中のメソッドを呼び出したメソッドの集合を返します。

GetSubClassesは同じオブジェクト内にGetControllerNamesと呼ばれ、ヘルパーアセンブリを返す必要があります。

編集:MSDNのドキュメント上の特記事項から

GetCallingAssemblyメソッドを呼び出す方法は、ジャストインタイム(JIT)コンパイラによって インライン展開されている場合は

場合、または呼び出し元が インライン展開されている場合、GetCallingAssembly によって返されるアセンブリが予期せず異なる場合があります。たとえば、次のメソッド とアセンブリを考えてみます。

アセンブリA1のメソッドM1はGetCallingAssemblyを呼び出します。

アセンブリA2のメソッドM2はM1を呼び出します。

アセンブリM3のメソッドM3はM2を呼び出します。

M1がインライン化されていない場合、GetCallingAssemblyはA2を返します。 M1が の場合、GetCallingAssemblyはA3を返します。同様に、M2が でない場合、GetCallingAssemblyはA2を返します。 M2がインライン化されている場合、 GetCallingAssemblyはA3を返します。

のでGetSubClassesがインライン化されていない、それはGetControllerNamesが属するアセンブリを返すべきであると仮定。

+0

を参照してください、それはヘルパーアセンブリではありません。ヘルパーアセンブリは、現在実行中のアセンブリです。呼び出し元アセンブリは、このヘルパーメソッドを呼び出したアセンブリになります。これは、Razorビューを実行しているアセンブリです。 –

+0

@DarinDimitrov - MSDNのドキュメントが間違っていますか? –

+0

ダーリン、デバッグ時に、結果のアセンブリは、あなたが思うようにヘルパーアセンブリであり、ダイナミックビューアセンブリではありませんでした... –

0

私はGetCallingAssemblyが働いていると考えています。 GetControllerNamesの中でAssembly.GetCallingAssemblyを直接呼び出すと、別の結果が得られることがあります。

GetCallingAssemblyの動作はメソッドがインライン化されているかどうかに応じて変化させることができることに注意してください - ノーhttp://msdn.microsoft.com/en-us/library/system.reflection.assembly.getcallingassembly.aspx

関連する問題