49

Assembly.LoadとAssembly.ReflectionOnlyLoadの違いを理解しようとしています。

以下のコードでは、特定のインターフェイスから継承する特定のアセンブリ内のすべてのオブジェクトを検索しようとしています。

var myTypes = new List<Type>();

var assembly = Assembly.Load("MyProject.Components");

foreach (var type in assembly.GetTypes())
{
   if (type.GetInterfaces().Contains(typeof(ISuperInterface)))
   {
      myTypes.Add(type);
   }
}

このコードは私にとっては問題なく機能しますが、他のおそらくより良い代替案を調査していて、Assembly.ReflectionOnlyLoad()メソッドに出くわしました。

オブジェクトをロードまたは実行していないので、基本的には、ReflectionOnlyLoadを使用してパフォーマンスをわずかに向上させることができるという定義をクエリするだけだと思いました...

しかし、Assembly.LoadをAssembly.ReflectionOnlyLoadに変更すると、assembly.GetTypes()を呼び出すときに次のエラーが発生することがわかりました。

System.Reflection.ReflectionTypeLoadException:

要求されたタイプの1つ以上をロードできません。詳細については、LoaderExceptionsプロパティを取得してください。

上記のコードは、ライブラリを反映して「見る」だけだと思いました...しかし、これは、ライブラリとその中のオブジェクトを見ると、実際にライブラリをインスタンス化しようとするハイゼンベルグの不確定性原理の一種のインスタンスです。仕方?

ありがとう、マックス

4

5 に答える 5

28

ジョンの返事によると、何が入っているかを知ることは役に立ちますLoaderExceptions。この情報の代わりに、私は推測を危険にさらすことができると思います。MSDNから:

アセンブリに依存関係がある場合、ReflectionOnlyLoadメソッドはそれらをロードしません。それらを調べる必要がある場合は、自分でロードする必要があります。

AppDomain.ReflectionOnlyAssemblyResolveロードするアセンブリの依存関係をCLRがロードできるように、ハンドラーをアタッチする必要があります。あなたはこれをしましたか?

于 2008-11-20T17:14:51.917 に答える
11

ReflectionOnly メソッドは、通常の Load/LoadFrom 規則を経由せずに、特定の Assembly をディスクに読み込んで調べることができる唯一の方法です。たとえば、GAC のアセンブリと同じ ID を持つディスク ベースのアセンブリを読み込むことができます。LoadFrom または LoadFile でこれを試した場合、GAC アセンブリは常に読み込まれます。

さらに、返された Assembly インスタンスで GetCustomAttributes(...) を呼び出すことはできません。これは、ReflectionOnly であるアセンブリの属性をインスタンス化しようとするためです。これには CustomAttributeData クラスの静的メソッドを使用する必要があります。

ReflectionOnly を介して読み込まれたアセンブリ内の型はインスタンス化できません。

于 2008-11-20T20:02:54.540 に答える
10

Load と ReflectionOnlyLoad の違いに関する一般的な理解は正しいと思います。ここでの問題 (私が思うに) は、単純に型をロードする場合でも、型自体が定義されているアセンブリからメタデータを読み取るだけでなく、型の祖先が定義されているすべてのアセンブリからメタデータをロードする必要があることです。そのため、読み込んでいる型の先祖である型を定義するすべてのアセンブリで Assembly.ReflectionOnlyLoad を呼び出す必要があります。

たとえば、アセンブリ A.dll に次のクラスが定義されているとします。

public class MyBase
{
   public void Foo() { }
}

およびアセンブリ B.dll で定義されている次のクラス。

public class MySubclass : MyBase
{
}

アセンブリ B.dll で Assembly.GetTypes を呼び出すと、CLR は型 MySubclass とそのすべてのメンバーを読み込もうとします。メソッド Foo はアセンブリ A.dll の MyBase で定義されている (そして B.dll のメタデータには存在しない) ため、アセンブリ A.dll が読み込まれていない場合、CLR は型読み込み例外をスローします。

于 2008-11-20T18:12:16.573 に答える
3

でロードされたアセンブリからメソッドを実行することはできません。ReflectionOnlyLoad()を取得しInvalidOperationExceptionます。したがって、これはリフレクションを使用してアセンブリ コンテンツを決定する安全な方法です。

于 2009-03-19T13:44:27.767 に答える