调用加载到单独的应用程序域

时间:2016-09-13 04:02:01

标签: c#

我现在已经和它斗争了几天,并且在这种特殊情况下无法在谷歌上找到任何东西。我知道我想要做的事情是可能的,因为我已经与另一个应用程序一起工作了(退出游戏Photon)不幸的是,Photon不会在linux下运行,而我到目前为止所做的就是为什么我要尝试&# 34;重新发明轮子)

我有一个程序将一个程序集(插件类型的东西)加载到一个单独的App域然后拉动接口并可以运行我的程序集中类的接口中定义的函数但是我的程序集类继承自一个基类是另一个集会。我希望能够在基类上运行一个函数,而不必将它添加到派生类中,但我得到的只是异常

基类:

[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");
    }
}

现在我可以调用Setup,TearDown,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.Main(String [] args)

这是IApplicationBase接口:

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);它会显示值基类中的什么我只是无法弄清楚如何用参数调用基类构造函数

我尝试使用CreateInstanceAndUnwrap传递参数但是只是抛出了一个没有构造函数的异常

1 个答案:

答案 0 :(得分: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");
}
相关问题