近日在研究AppDomain相关的东西,对于AppDomain之间传递对象以及创建、卸载域方面有一定的心得,写出来与大家分享,如有不到之处欢迎排砖。
.net中Appdomain是个非常有用的概念,其进程级的独立性使得程序的处理有了更简洁的处理方式。我们目前项目中运用的比如远程exe的 Remoting加载和卸载、自动补丁等。这里描述一下AppDomain之间的对象传递和多个域的控制。
AppDomain传递对象等研究
近日在研究AppDomain相关的东西,对于AppDomain之间传递对象以及创建、卸载域方面有一定的心得,写出来与大家分享,如有不到之处欢迎排砖。
.net中Appdomain是个非常有用的概念,其进程级的独立性使得程序的处理有了更简洁的处理方式。我们目前项目中运用的比如远程exe的 Remoting加载和卸载、自动补丁等。这里描述一下AppDomain之间的对象传递和多个域的控制。
1. 域的传值
域的传值方式包括AppDomain的createInstance,Remoting,以及WCF等第三方媒介都可以实现。其中Remoting和WCF都需要建立端口侦听,对于企业级的应用这种方式还算是比较合适;但是也存在一定的不足,如果建立的侦听端口没有及时释放就会出问题(个人对于这类问题是比较反感的);因此在本文采用CreateInstance方式。
多个域的协同工作中,如果采用CreateInstance方式则需要,需要知道目标域的实例才可以跨域获取数据。下面的例子提供了一种域的实例的跨域全局保存的方法,程序在任何地方均可得到全部域的实例,那么跨域存储数据将迎刃而解。
2. 域的创建
本文将应用程序启动时的域称为启动域,首先创建域时封装了一个方法将启动域保存在新域中。

Code
1
AppDomain _domain = AppDomain.CreateDomain(domainFrindlyName, StartDomain.Evidence, domainSetup);
2
_domain.SetData(START_DOMAIN_DATA_FLAG, StartDomain);
启动域的获取方式如下:

Code
1
private AppDomain _startdomain = null;
2
private AppDomain StartDomain
3
{
4
get
{
5
if (_startdomain == null)
6
{
7
_startdomain = AppDomain.CurrentDomain.GetData(START_DOMAIN_DATA_FLAG) as AppDomain;
8
if (_startdomain == null)
9
_startdomain = AppDomain.CurrentDomain;
10
}
11
return _startdomain;
12
}
13
}
3. 域列表的获取与保存

Code
1
public DomainList LoadDomainList()
2
{
3
RemoteDomainUtil _domainutil = StartDomain.CreateInstanceAndUnwrap("DomainUtilPrj", "DomainUtilPrj.RemoteDomainUtil") as RemoteDomainUtil;
4
if (_domainutil == null)
5
throw new Exception("Remote create instance RemoteDomainUtil error");
6
return _domainutil.RemoteLoadDomainList();
7
}
8
9
private void SetDomainList(DomainList domainList)
10
{
11
RemoteDomainUtil _domainutil = StartDomain.CreateInstanceAndUnwrap("DomainUtilPrj", "DomainUtilPrj.RemoteDomainUtil") as RemoteDomainUtil;
12
if (_domainutil == null)
13
throw new Exception("Remote create instance RemoteDomainUtil error");
14
_domainutil.RemoteSetDomainList(domainList);
15
}

Code
1
public AppDomain CreateOrLoadDomain(AppDomainSetup domainSetup, string domainFrindlyName)
2
{
3
DomainList _domainlist = LoadDomainList();
4
if (_domainlist.AllAppDomain.ContainsKey(domainFrindlyName))
5
return _domainlist[domainFrindlyName];
6
7
AppDomain _domain = AppDomain.CreateDomain(domainFrindlyName, StartDomain.Evidence, domainSetup);
8
_domain.SetData(START_DOMAIN_DATA_FLAG, StartDomain);
9
10
_domainlist.AddDomain(domainFrindlyName, _domain);
11
SetDomainList(_domainlist);
12
return _domain;
13
}
通过上面的方法我们可以在任何域中获取域列表。那么剩下的跨域传递对象将不再是难事,此处不再描述。
总结:通过以上的方式可以获取特定的域,但是跨域调用数据会加载另一个域中类库,会增加类库之间的耦合