从其他 .dll 加载服务并隔离运行

Posted

技术标签:

【中文标题】从其他 .dll 加载服务并隔离运行【英文标题】:Loading services from other .dll and run them isolated 【发布时间】:2011-03-21 15:59:32 【问题描述】:

我想以隔离的方式运行来自不同 .dll 的多个服务。基本上,所有服务都来自 RoleEntryPoint ,我想将每个服务加载到单独的 AppDomain 中,并在不同的线程中运行。

到目前为止,我可以找到服务并获取其类型:

        String pathToDll = @"C:\....\bin\Debug\ChildWorkerRole.dll"; 
        Assembly assembly = Assembly.LoadFrom(pathToDll);
        Type serviceType = assembly.GetTypes().SingleOrDefault(t => t.BaseType == typeof(RoleEntryPoint));

并且也在当前的AppDomainThread中运行:

        RoleEntryPoint myRole2 = (RoleEntryPoint)Activator.CreateInstance(serviceType);
        if (myRole2.OnStart())
            myRole2.Run();

但是当我尝试在不同的 AppDomain 中单独运行它时,我得到一个异常:

        AppDomain domain = AppDomain.CreateDomain("MyNewDomain");
        RoleEntryPoint myRole = (RoleEntryPoint)domain.CreateInstanceFromAndUnwrap(pathToDll, serviceType.FullName);
        if (myRole.OnStart())
            myRole.Run();

这个例外:

System.Runtime.Serialization.SerializationException was unhandled
  Message=Type 'ChildWorkerRole.WorkerRole' in assembly 'ChildWorkerRole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
  Source=mscorlib
  StackTrace:
       at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
.......

有趣的是ChildWorkerRole实际上标有SerializableAttribute...但可能是因为RoleEntryPoint没有,所以无法做到。

有什么想法或解决方法吗?

谢谢!

【问题讨论】:

【参考方案1】:

为了在单独的 AppDomain 中使用类型,它以及您直接使用的所有类型都需要标记为 [Serializable],或者您需要从 MarshalByRefObject 派生它们。

如果这不可能,唯一真正的选择是创建一个您可以使用的代理类,它确实遵循上述标准,并允许它在内部管理您的类型。

【讨论】:

以上是关于从其他 .dll 加载服务并隔离运行的主要内容,如果未能解决你的问题,请参考以下文章

AppDomain 隔离问题

终端服务器会话中的隔离命名管道

突破SESSION 0隔离的远程线程注入

微服务系列之Hystrix服务容错

隔离(无注册)COM 组件行为

从后台颤振隔离向Android方法发送平台消息