質問全体を読んでください。いくつかの制約を解決したいという独特の状況があります。
私のコードには、にコンパイルされた式ツリーがありPredicate<System.Type>
ます。私の目標は、アセンブリをロックせずにロードし (プロジェクトの出力アセンブリであり、常に再構築されます)、その型のリストにこの述語を適用し、結果の型名のリストを取得することです。
// this is what I need:
return assembly.GetTypes().Where(t => predicate(t)).Select(t => t.FullName);
必要な情報を取得したらすぐにアンロードしたいので、このアセンブリは別のアプリケーション ドメインにロードする必要があります。
ここがややこしいところです。私が直面しているいくつかの問題があります:
アセンブリを別のアプリドメインにロードし、そのすべての型の配列を返すだけで、述語をメインのアプリドメインに適用できるようにすると、型がメインのアプリドメインにマーシャリングされるとすぐに、次のようになりますFileNotFoundException
。このアセンブリが見つかりません。アセンブリは、私が作成した別の appdomain にのみ読み込まれるため、これは理にかなっています。メインのアプリドメインにもロードすると、目的が無効になります。
または、述語を他のアプリケーション ドメインに渡してそこに適用し、文字列の配列 (完全な型名) を取得しようとするSerializationException: "Cannot serialize delegates over unmanaged function pointers, dynamic methods or methods outside the delegate creator's assembly."
と、述語が動的メソッド (式ツリーからコンパイル) であるため、が返されます。 .
プライマリ appdomain にロードすると、この問題は発生しませんが、appdomain 全体をアンロードせずにロード済みのアセンブリをアンロードすることは不可能であるため、(再構築後に) アセンブリが変更されるとすぐに、同じ名前のアセンブリをロードしようとすると、例外が発生します。
コンテキスト: Agent Mulder
という ReSharper のプラグインを作成しています。プラグインの背後にあるアイデアは、ソリューション内の DI/IoC コンテナーの登録を分析し、ReSharper が DI コンテナーを介して登録された型の使用法を把握できるようにすることです (仕組みの短いビデオをここで見ることができます)。
ほとんどの場合、コンテナー登録の分析は簡単です。どの具象型が影響を受けるかを知るのに十分な情報を検出するだけで済みます。Castle Windsor を使用したこの例でComponent.For<IFoo>().ImplementedBy<Foo>()
は、結果の型は明らかですAllTypes.FromThisAssembly().BasedOn<IFoo>()
。つまり、この行によって影響を受ける具体的な型を推定するのに十分な情報が得られます。ただし、Castle Windsor での次の登録を検討してください。
container.Register(Classes
.FromAssemblyInDirectory(new AssemblyFilter(".").FilterByName(an => an.Name.StartsWith("Ploeh.Samples.Booking")))
.Where(t => !(t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Dispatcher<>)))
.WithServiceAllInterfaces());
(ソース)
ここでの情報は、実行時にのみ評価される述語に依存します。
私にできることはこれを静的に分析することだけなので、Where
節からのラムダ式の ReSharper の AST (ReSharper では PSI と呼ばれる) 表現を手にしています。この AST を LINQ 式ツリーに変換し、デリゲートにコンパイルできます。
私の考えは、FromAssembly*
リフレクションを介して出力アセンブリ (記述子によって決定される) をロードし、このデリゲートをアセンブリの型に適用して、型名を取得することでした (名前のみが必要です)。これも、アセンブリが変更されるたびに再評価する必要があります (この時点では、パフォーマンスについては心配していません)。
結論として、誰かが述語の影響を受ける型を判断するためのより良い方法を推奨できない限り、リフレクションでこれを行う方法を知りたいです (残念ながら、他のメタデータ リーダーを考慮していませんでした。ラムダ式 AST を異なるデータ型の述語に変換する必要があり、1 対 1 の変換が存在するかどうかはわかりません)。
読んでくれてありがとう。この質問が利用可能になると、500 ポイントの報奨金が与えられます。