2011-02-09 10 views
4

注:すべてのサンプルコードは大幅に簡素化されています。C#プロジェクトに含まれていないオブジェクトをどのようにインスタンス化しますか?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Web; 

namespace RIV.Module 
{ 
    public interface IModule 
    { 
     StringWriter ProcessRequest(HttpContext context); 
     string Decrypt(string interactive); 
     string ExecutePlayerAction(object ParamObjectFromFlash); 
     void LogEvent(object LoggingObjectFromFlash); 
    } 
} 

さて、私の解決策の外に、他の開発者が具体的なクラスを定義することができますし、私のアプリのBINフォルダにドロップ:

私はとDLLが定義されています。多分何か:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using RIV.Module; 

namespace RIV.Module.Greeting 
{ 
    public class Module : IModule 
    { 
     public System.IO.StringWriter ProcessRequest(System.Web.HttpContext context) 
     { 
      //... 
     } 
     public string Decrypt(string interactive) 
     { 
      //... 
     } 
     public string ExecutePlayerAction(object ParamObjectFromFlash) 
     { 
      //... 
     } 
     public void LogEvent(object LoggingObjectFromFlash) 
     { 
      //... 
     } 
    } 
} 

、私のアプリでは、私は新しいモジュールがオフに基づいて、それを呼び出すことができ、次に利用できる(私はweb.configファイルまたはそれらの線に沿って何かを経由して推測しています)としたことを知っておく必要があります(特定のキャンペーンに使用するモジュールにマップされている)データベースキャンペーンテーブルのトリガーの一部です。

私はそれをこのようにインスタンス化しようとしています:

var type = typeof(RIV.Module.Greeting.Module); 
var obj = (RIV.Module.Greeting.Module)Activator.CreateInstance(type); 

しかし、コンパイラが参照がRIV.Module.Greeting.dllに設定されていなかったのでbelches!

私は間違っていますか?

+0

これらのモジュールをどうすればいいのか分かりますか? –

+0

@Anon:彼のインタフェースを使用しています。 – SLaks

+0

ここで、どの時点でインスタンス化しようとしていますか? – deostroll

答えて

1

代わりのtypeof演算(RIV.Module.Greeting.Module)、

var type = Type.GetType("RIV.Module.Greeting.Module, RIV.Module.Greeting"); 

(すなわち文字列としてそのアセンブリ修飾名を指定することにより、タイプをロード)とはIModuleにキャストを使用してみてください。

この手法では、モジュールの正確なクラス名とアセンブリ名を知っておく必要があります(記述したとおり、web.configに格納することができます)。

また、あなたは完全に動的プラグインのアプローチのために行くことができます:

  1. は、すべてのモジュールアセンブリは、DLLを
  2. をマッチングするためのbinディレクトリをスキャン「RIV.Module.XYZ」
  3. 命名されなければならない規則を確立します各DLLについて
  4. 、はIModule
に見つかったすべてのタイプとキャストを(例えばAssembly.Loadを)それをロードしてはIModule
  • インスタンス化を実装するタイプをスキャン
  • +0

    これは、ローダーがアセンブリを単独で見つけることができる場合にのみ機能します。 (もしあなたが 'AssemblyResolve'を扱うならば) – SLaks

    +0

    私は、新しいAppモジュールがCreate/Edit/Publishパイプラインを介して送られ、Assembly、Type&Pathがモジュールと呼ばれるDBテーブルに格納されるアプローチをもっと考えていました**公開**があれば、クライアントベースで利用可能となります)。 –

    +0

    遅れて申し訳ありません。クライアントアプリケーションがサーバからモジュールをダウンロードする場合(DBに格納されている場合)、静的コンフィグレーションは必要ありません。クライアントはサーバに利用可能なモジュールを問い合わせ、アセンブリをダウンロードしてローカルディレクトリにキャッシュします次に、私が書いた動的ロードロジックを呼び出します(ディスカバリ部分を除いて、クライアントは既にロードするモジュールとそのア​​センブリと型名を知っています)。 –

    2

    あなたはより多くの反射を使用する必要があります。

    • にキャストActivator.CreateInstance
    • Typeインスタンスを渡しsomeAssembly.GetType(name)を呼び出すか、someAssembly.GetTypes()
    • を検索してタイプを探すAssembly.Load
    • を呼び出すことによって、アセンブリをロードしますあなたのインターフェイス。
    関連する問題