2016-09-13 13 views
0

私はこれで数日間戦ってきましたが、この特定の状況についてはGoogleで何も見つかりませんでした。私はそれをしている別のアプリケーション(Exit game Photon)で働いているので、私がやりたいことが可能であることを知っています。Photonは残念ながらLinuxの下では動作しません。そして、これまでのところ私は "ホイール)別のアプリケーションドメインにロードされたアセンブリ内のクラスの基本クラスを呼び出す

私は別のアプリケーションドメインにアセンブリ(プラグインタイプのもの)をロードしてからインターフェイスをプルするプログラムを持っていて、アセンブリのクラスのインターフェイスで定義されたfuctionsを実行できますが、別のアセンブリである基底クラスIは、派生クラスに追加することなく、基本クラスののfuctionを実行できるようにしたいが、私が得るすべては例外

基本クラスです。

[Serializable] 
public abstract class ApplicationBase : MarshalByRefObject, IApplicationBase 
{ 
    public abstract void SetUp(); 
    public virtual void TearDown() { } 
    public virtual void OnStopRequested() { } 

    public virtual void OnServerConnectionFailed(int errorCode, string errorMessage, object state) 
    { 
     //Do nothing this is only for the individual servers 
    } 
} 

テストサーバークラス:

public class TestServer : ApplicationBase 
{ 
    protected readonly ILogger Log = LogManager.GetLogger("TestServer"); 

    public override void SetUp() 
    { 
     Log.Debug("Setup"); 
    } 

    public override void TearDown() 
    { 
     Log.Debug("TearDown"); 
    } 

    public override void OnServerConnectionFailed(int errorCode, string errorMessage, object state) 
    { 
    } 

    public override void OnStopRequested() 
    { 
     Log.Debug("Stop Requested"); 
    } 
} 

今私は、セットアップ、ティアダウン、OnStopRequestedのいずれかを呼び出すか、私のプラグイン・クラスはそれらをオーバーライドするようOnServerConnectionFailedことができます。私はロガー出力を取得します。私のようなもの置く場合 :、基底クラスに

public void Configure(string val1, string val2) 
    { 
     //Initialize the values 
    } 

を、私は次のコードでプラグインをインスタンス化した後:

ApplicationPath = $"{DeployPath}\\{AppConfig.BaseDirectory}\\bin"; 
     if (!File.Exists(ApplicationPath + "\\" + AppConfig.Assembly + ".dll")) Console.WriteLine("ERROR {0} Not found", AppConfig.Assembly); 
     AppDomainSetup adSetup = new AppDomainSetup 
     { 
      ApplicationBase = ApplicationPath, 
      ApplicationName = AppConfig.Name, 
      PrivateBinPath = ApplicationPath, 
      ShadowCopyFiles = "true", 
      ShadowCopyDirectories = ApplicationPath 
     }; 
     _appDomain = AppDomain.CreateDomain(string.Format("{0} AppDomain", AppConfig.Assembly), null, adSetup); 
     _application = (IApplicationBase)_appDomain.CreateInstanceAndUnwrap(AppConfig.Assembly, AppConfig.Type); 

私はその後、_application.Configure("one","two"); を呼び出そうとした場合、私は次の例外を取得します:

未処理の例外:System.MissingMethodException:メソッドが見つかりません: 'Void EmpireHostRuntimeInterfaces.IApplicationBase.Configure(System.String、 System.String) 'を返します。 SocketServer.Program.Start() (SocketServer.Program) にあります。メイン(文字列[] args)を

これはIApplicationBaseインタフェースである:基底クラスが機能していないdirevedクラスを定義しているので、私はその投げ、その例外を伝えることができるものから今

public interface IApplicationBase 
{ 
    void Configure(string val1, string val2); 
    void SetUp(); 
    void TearDown(); 
    void OnServerConnectionFailed(int errorCode, string errorMessage, object state); 
    void OnStopRequested(); 
} 

けど最終的にはこれを他の人が使用するためにリリースするつもりで、基底クラスの関数を呼び出す必要があります。これは、派生クラスに対して透過的である必要があるためです(メインサーバーの設定からいくつかの情報をサブアプリケーション)

私がベースに入れたもの私は私のプラグインの派生クラスからアクセスすることができます(例えば、public string ApplicationName = "Application1"を基底クラスに入れ、派生クラスでLog.Debug(ApplicationName);を呼び出すと、基本クラスのwhatsの値が表示されます)私はどのように私はCreateInstanceAndUnwrapで引数を渡す試してみましたが、それは単にその「正しい」方法は、しかし、私はへの道を考え出した場合にはコンストラクタが

答えて

0

わからない例外見つからない投げた引数

と基底クラスのコンストラクタを呼び出すためにこれを行うには、必要なフィールドを持つApplicationDataクラスを作成し、新しいApplicationDataクラスをインスタンス化し、プラグインのベースクラスがアクセスできるAppDomainデータエリアに追加します。

ApplicationData data = new ApplicationData {ApplicationName = AppConfig.Name, BinaryPath = ApplicationPath}; 
_appDomain.SetData("Data", data); 

はその後、私の基本クラスで私はパラメータなしのコンストラクタを追加しました:

protected ApplicationBase() 
{ 
    _appData = (ApplicationData)AppDomain.CurrentDomain.GetData("Data"); 
} 
関連する問題