2016-12-29 7 views
-1

私は(IModuleがインターフェイスであるので、私は、プラグインが正常に動作します知っている)私は、動的に自分のアプリケーションにクラスをロードすることができますプラグインシステムを構築していますプラグインからクラスインスタンスを取得するにはどうすればよいですか?

var dll = Assembly.LoadFile("path/to/a/dll"); 
foreach (Type t in dll.GetExportedTypes()) { 
     if (typeof(IModule).IsAssignableFrom(t)) { 
      IModule mod = (IModule)Activator.CreateInstance(t); 
     } 
} 

だから、私の「メイン」アプリケーションから、私はプラグインでクラスを取得してインスタンス化できます。私が今好きなのは、プラグインから "メイン"アプリケーションのクラスに到達できることです。

Type.GetType("NameOfClass")を試しましたが、それはnullを返します。

+0

これは問題ではないようです。どこにこだわっていますか? – adv12

+0

クラスインスタンスの取得は、クラスの名前にのみ基づいています。 –

+0

なぜこの方向に反射を使用するのですか?どうしてあなたのプラグインプロジェクトからアプリを参照し、クラスを直接参照しないでください? – adv12

答えて

0

これは、メインモジュールをまったく変更せずに行う必要がある場合には醜い状態になる可能性があります。したがって、以下の提案はクルージングですが、この場合、クルーギーがあなたが望む最高のものと思われます。

静的メソッドAssembly.GetCallingAssembly()は、現在のメソッドを呼び出したアセンブリを返します。そのため、メインモジュールが直接プラグインモジュールの一部のメソッドMを呼び出す場所を見つけることができます。指が交差していて、初期に呼び出される初期化メソッドのようなものがあるかもしれません。

Mには、Assembly.GetCallingAssembly()を呼び出し、後でメインモジュールで定義されたクラスのインスタンスを作成するために使用できる静的フィールドに結果を埋め込みます。

+0

ありがとうございます。私はそれがクルージであることを知っていて、それは醜いですが、私は本当にそれが可能かどうかを知りたいと思っていました。これが唯一の方法であり、このクルジーであることが分かった場合、結局、それを「正しい」方法で固定することを検討するかもしれません。 –

0

あなたはプラグインのような概念を誤解していると思います。パブリックプラグインインタフェースを格納する目的のAPIライブラリを実装する必要があります。あなたがあなたのプラグインで使用しているインターフェースで、いくつかのIoCフレームワークを通してクラスをインスタンス化するだけです。

public class MyPlugin : IModule 
{ 
    public MyPlugin(MainApp.API.IMainAppInterface instance) 
    { 
     //do something with it. 
    } 
} 

public class MyPluginModule: NinjectModule 
{ 
    protected override void Load(IKernel kernel) 
    { 
     kernel.Bind<MyPlugin>().To<IModule>(); 
    } 
} 

をそして、あなたのメインアプリケーションであなただけのいくつかのフォルダからこれらのモジュールをロードします。たとえば、Ninjectを使用することができます。

+0

私はそれをやっていますが、いくつかのクラスをAPIに入れるのを忘れていました。問題は今、APIを更新する必要があるか、またはAPI dllまたはメインアプリケーションに触れることなくこれを行う方法があるかどうかです。 –

+0

アプリケーションの内部機能にアクセスするには、APIを更新する必要があります。共通のAPIライブラリを更新する必要はなく、独自のプラグインを追加してプラグインで使用するだけです。これをハックしたいのであれば、おそらく多くの反射されたコードが生成されてしまいます。どのように動作するのか誰も知りません... – eocron

+0

"迷惑なコードを反映させる"ことができますか? –

関連する問題