2009-03-31 10 views
65

与えられた名前空間の下で、私はインターフェイスを実装するクラスのセットを持っています。それをISomethingとしましょう。私はISomethingを知っているが、そのインターフェースを実装するクラスについて知らない別のクラス(CClassと呼ぶ)を持っています。与えられたインタフェースを実装するすべてのクラスを見つけるには?

私はCClassのすべての実装を探して、ISomethingのインスタンスをインスタンス化し、そのメソッドを実行したいと思います。

誰かがC#3.5でそれを行う方法についてアイデアを持っていますか?

+2

に[C#3.0とのインタフェースを実装するすべての種類を取得する]の可能な複製を行く必要があります(http://stackoverflow.com/questions/26733/getting-all型定義 - その - 実装 - インターフェイス - Cシャープ-3-0) –

答えて

127

作業コードサンプル:

var instances = from t in Assembly.GetExecutingAssembly().GetTypes() 
       where t.GetInterfaces().Contains(typeof(ISomething)) 
         && t.GetConstructor(Type.EmptyTypes) != null 
       select Activator.CreateInstance(t) as ISomething; 

foreach (var instance in instances) 
{ 
    instance.Foo(); // where Foo is a method of ISomething 
} 

編集のCreateInstanceの呼び出しが成功するように、パラメータなしのコンストラクタのチェックを追加しました。あなたはこれを使用してロードされたアセンブリのリストを取得することができます

+9

小さなクリーンアップの提案 - 新しい空の型配列をインスタンス化するのではなく、Type.EmptyTypesを使用します。 –

+0

ロードされたすべてのアセンブリでこれを行う方法はありますか?用事 – gregmac

+13

.. AppDomain.CurrentDomain.GetAssembliesにアセンブリから VaRのインスタンス=() assembly.GetTypes t.GetInterfaces()() におけるTから。(typeof演算(ISomething))が含ま && t.GetConstructor(タイプ.EmptyTypes)!= null Activator.CreateInstance(t)をISomethingとして選択します。 – gregmac

8

のLINQを使用した例:

var types = 
    myAssembly.GetTypes() 
      .Where(m => m.IsClass && m.GetInterface("IMyInterface") != null); 
2

次のようなものを使用し、あなたのニーズに合わせてカスタマイズできます。

var _interfaceType = typeof(ISomething); 
var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly(); 
var types = GetType().GetNestedTypes(); 

foreach (var type in types) 
{ 
    if (_interfaceType.IsAssignableFrom(type) && type.IsPublic && !type.IsInterface) 
    { 
     ISomething something = (ISomething)currentAssembly.CreateInstance(type.FullName, false); 
     something.TheMethod(); 
    } 
} 

このコードではいくつかの機能拡張が使用できますが、これが始まりです。

9

Assembly assembly = System.Reflection.AppDomain.CurrentDomain.GetAssemblies() 

そこから、(パブリック型を仮定して)アセンブリ内の型のリストを取得することができます。

Type[] types = assembly.GetExportedTypes(); 

その後オブジェクト上のそのインタフェースを見つけることによって、そのインタフェースをサポートするかどうかをそれぞれの型に尋ねることができます。

Type interfaceType = type.GetInterface("ISomething"); 

リフレクションでこれを行うより効率的な方法があるかどうかは不明です。

3
foreach (Type t in Assembly.GetCallingAssembly().GetTypes()) 
{ 
    if (t.GetInterface("ITheInterface") != null) 
    { 
     ITheInterface executor = Activator.CreateInstance(t) as ITheInterface; 
     executor.PerformSomething(); 
    } 
} 
0

たぶん、私たちはこのよう

foreach (var instance in Assembly.GetExecutingAssembly().GetTypes().Where(a => a.GetConstructor(Type.EmptyTypes) != null).Select(Activator.CreateInstance).OfType<ISomething>()) 
    instance.Execute(); 
関連する問題