NET对象的跨应用程序域

转眼就到了元宵节,匆匆忙忙的脚步是我们在为生活奋斗的写照,新的一年,我们应该努力让自己有不一样的生活和追求。生命不息,奋斗不止。在上篇博文中主要介绍了.NET的AppDomain的相关信息,在本篇博文中将会主要说明.NET程序集、对象代理,以及对象的封送原理。

一.程序集解析:

谈到程序集,就要知道什么叫做程序集,我们看看程序集的定义是什么。程序集大致分为两种:一种是类库(就是我们看到的.DLL文件);一种是可执行程序(就是我们看到的.EXE文件)。程序集是一个或多个模块/资源文件的逻辑分组(一个模块成为单模块程序集或者单文件程序集;多个模块成为多模块程序集或者多文件程序集);程序集是重用、安全性以及版本控制的最小单元。程序集的主要构成,请看下面的图示:

程序集并不一定对应唯一的一个文件,也可以包含多个文件,在多个文件组成的程序集中,包含程序集清单的文件称为主模块,每个程序集都必须包含一个主模块,并且只有一个。对于程序集更加详细的介绍,在另一篇博文中有所介绍,在这里就不在赘述,博文地址:http://www.cnblogs.com/pengze0902/p/6043525.html

二.DotNet的对象代理解析:

1.对象代理概述:

本文主要是讲解对象的跨应用程序域访问,前面介绍了应用程序域和程序集的相关信息,在这里就要开始讲解如何来实现对象的跨应用程序域的访问操作。对象跨应用程序域的操作需要知道代理和封送,代理提供了和远程对象完全相同的接口,代理有着和远程对象完全一样的接口和名称,对于客户端而言,代理就好像远程对象一样。但是代理并不包含向客户端程序提供服务的实际代码,代理仅仅是将自己与某一实际对象绑定,然后将客户端对自己的请求打包为消息,然后发送给实际对象。

在这里首先介绍一下代理,就需要知道两个名词“透明代理”和“真实代理”。有如下图所示:

    透明代理是由CLR创建的一种特别对象,主要是为了将方法调用转换成消息交换。由上图可以看到透明代理和真实代理,透明代理和真实代理是一一对应的关系。透明代理对象最终必须充当一个特定的类型的实例。

一个程序获得透明代理的引用后,这个程序将在代理对象上使用方法调用。当程序在透明代理对象上使用方法调用时,CLR将创建一个新的消息对象以表示这个调用,CLR会将这个消息传递给真实代理用于处理。

真实代理将产生另外一条消息,以表示调用的结果,透明代理将使用第二条消息对这个调用的对战进行转化,透明地将结果传送给调用方。如果真实代理返回的响应消息包含异常,透明代理将再次抛出这个异常,并再一次将结果传给调用方。

透明代理和真实代理之间的消息交换是通过真实带来的Invoke方法发生。在透明代理对象上的方法调用,导致从基于堆栈处理的信息转换为基于消息处理的方式。再返回响应消息之前,真实代理的Invoke实现可能将消息分发给任何数量的处理节点,为了传送调用到的一个实际对象,最终的处理节点归根结底都需要将请求消息转换为堆栈帧。

2.对象代理原理解析:

上面主要介绍了代理的一些基本理论,下面看一下这些核心对象。

(1).RealProxy.GetTransparentProxy():返回 RealProxy 的当前实例的透明代理。

  public virtual object GetTransparentProxy()
{
return this._tp;
}

该方法在System.Runtime.Remoting.Proxies命名空间下,RealProxy类:提供代理的基本功能。

(2).ProxyAttribute.CreateProxy():创建由指定的 ObjRef描述并位于服务器上的远程对象的远程处理代理的实例。

[SecurityCritical]
public virtual RealProxy CreateProxy(ObjRef objRef, Type serverType, object serverObject, Context serverContext)
{
RemotingProxy remotingProxy = new RemotingProxy(serverType);
if (serverContext != null)
RealProxy.SetStubData((RealProxy) remotingProxy, (object) serverContext.InternalContextID);
if (objRef != null && objRef.GetServerIdentity().IsAllocated)
remotingProxy.SetSrvInfo(objRef.GetServerIdentity(), objRef.GetDomainID());
remotingProxy.Initialized = true;
Type type = serverType;
if (!type.IsContextful && !type.IsMarshalByRef && serverContext != null)
throw new RemotingException(Environment.GetResourceString("Remoting_Activation_MBR_ProxyAttribute"));
return (RealProxy) remotingProxy;
}

该方法在 System.Runtime.Remoting.Proxies命名空间下,ProxyAttribute类指示对象类型需要自定义代理。该方法接收5个参数,objRef:对要为其创建代理的远程对象的对象引用;serverType:远程对象所在的服务器的类型;serverObject:服务器对象;serverContext:服务器对象所在的上下文。该方法在指定的 <see cref="T:System.Runtime.Remoting.ObjRef"/> 中说明的远程对象的远程处理代理的新实例。

(3).RemotingServices:提供多种使用和发布远程对象及代理的方法。此类不能被继承。

GetRealProxy()方法返回指定透明代理后面的真实代理。

 [SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern RealProxy GetRealProxy(object proxy);

该方法接收参数,proxy:一个透明代理。该方法返回透明代理后面的真实代理实例。

IsTransparentProxy()方法返回一个布尔值,该值指示给定的对象是透明代理还是实际对象。

[SecuritySafeCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern bool IsTransparentProxy(object proxy);

该方法接收一个参数,proxy:参数对要检查的对象的引用。该方法返回指定的对象是透明代理还是实际对象。

ExecuteMessage():连接到指定的远程对象,并对其执行提供的 <see cref="T:System.Runtime.Remoting.Messaging.IMethodCallMessage"/>。

  [SecurityCritical]
public static IMethodReturnMessage ExecuteMessage(MarshalByRefObject target, IMethodCallMessage reqMsg)
{
if (target == null)
throw new ArgumentNullException("target");
RealProxy realProxy = RemotingServices.GetRealProxy((object) target);
if (realProxy is RemotingProxy && !realProxy.DoContextsMatch())
throw new RemotingException(Environment.GetResourceString("Remoting_Proxy_WrongContext"));
return (IMethodReturnMessage) new StackBuilderSink(target).SyncProcessMessage((IMessage) reqMsg);
}

该方法接收两个参数,target:要调用其方法的远程对象。reqMsg:指定的远程对象的方法的方法调用消息。该方法知识简单地为目标对象创建一个堆栈生成器,并且发送一个消息给这个接收器。堆栈生成器接收器处理底层的堆栈操作,并且调用实际的方法。当方法终止时,堆栈生成器接收器把作为结果的堆栈帧转换为响应的消息,CLR用它作为该方法调用的结果返回。

三.DotNet的对象封送解析:

上面介绍了代理,下面简单的介绍一下对象的封送,对象的封送分为两种,第一种为传值封送;第二种为传引用封送。

1.传值封送:

当位于A应用程序域的对象传递给B应用程序域,.NET将A中对象的状态进行复制、序列化、然后在B中重新创建,并通过代理对象进行访问。

(1 传值封送)                                                           (2 传引用封送)

2.传引用封送:

传引用封送的结构如上图所示,当客户端在代理调用方法时,由代理将对方法的请求发送给远程对象,远程对象执行方法请求,最后再将结果传回给客户端,这种方法叫做传引用封送。传引用封送分为三种不同的方式,分为客户端激活(Client Activated)、服务端激活Singleton(Server Activated Singleton)、服务端激活SingleCall(Server Activated SingleCall)。三种方式的共同特点,服务对象创建且一直保持在宿主应用程序中。

传引用封送的方式在这里就不做详细介绍了。

四.总结:

对象的跨应用程序域方法的问题就介绍这么多,希望对大家有所帮助。

NET对象的跨应用程序域的更多相关文章

  1. 解析.NET对象的跨应用程序域访问--AppDomain(上篇)

    在目前的项目开发中,分布式开发已经逐渐成为主流.一个项目要是没有采用分布式架构,都不好意思跟别人说这是一个完整的项目.这句话虽然有些过激,但是随着人们对效率的要求在提高,以及产品需要提升用户体验.只有 ...

  2. 解析.NET对象的跨应用程序域访问(下篇)

    转眼就到了元宵节,匆匆忙忙的脚步是我们在为生活奋斗的写照,新的一年,我们应该努力让自己有不一样的生活和追求.生命不息,奋斗不止.在上篇博文中主要介绍了.NET的AppDomain的相关信息,在本篇博文 ...

  3. 解析.NET对象的跨应用程序域访问(上篇)

    在目前的项目开发中,分布式开发已经逐渐成为主流.一个项目要是没有采用分布式架构,都不好意思跟别人说这是一个完整的项目.这句话虽然有些过激,但是随着人们对效率的要求在提高,以及产品需要提升用户体验.只有 ...

  4. 【.net 深呼吸】跨应用程序域执行程序集

    应用程序域,你在网上可以查到它的定义,凡是概念性的东西,大伙儿只需要会搜索就行,内容看了就罢,不用去记忆,更不用去背,“名词解释”是大学考试里面最无聊最没水平的题型. 简单地说,应用程序域让你可以在一 ...

  5. WPF 跨应用程序域的 UI(Cross AppDomain UI)

    为自己写的程序添加插件真的是一个相当常见的功能,然而如果只是简单加载程序集然后去执行程序集中的代码,会让宿主应用程序暴露在非常危险的境地!因为只要插件能够运行任何一行代码,就能将宿主应用程序修改得天翻 ...

  6. 跨应用程序域(AppDomain)的单例(Singleton)实现

    转载自: 跨应用程序域(AppDomain)的单例(Singleton)实现 - CorePlex代码库 - CorePlex官方网站,Visual Studio插件,代码大全,代码仓库,代码整理,分 ...

  7. django之 使用views.py里面的函数对表进行增删改查 内容(models.py中表的创建、views.py中函数的使用,基于对象的跨表查询)

    models之对于表的创建有以下几种: 一对一:ForeignKey("Author",unique=True),  OneToOneField("Author" ...

  8. python 全栈开发,Day73(django多表添加,基于对象的跨表查询)

    昨日内容回顾 多表方案: 如何确定表关系呢? 表关系是在2张表之间建立的,没有超过2个表的情况. 那么相互之间有2条关系线,先来判断一对多的关系. 如果其中一张表的记录能够对应另外一张表的多条记录,那 ...

  9. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

随机推荐

  1. 【Lua】Lua + LWT + ExtJS构建目录树

    Lua处理后台逻辑,Lua lwt搭建后台程序,ExtJS根据后台传来的json数据构建目录树. 前台html和ExtJS代码不用多讲,直接上代码: treePanel.html <html&g ...

  2. 关于重绘and重排

    在研究CSS3动画性能的时候,看到了重排两个字. 突然想到自己虽然听说过这么个东东,但一直也没深入研究之. 趁着当下正好有研究的劲头,所以一不做二不休,把这个point也给学习了. 同样是一番查找资料 ...

  3. java.lang.NumberFormatException: For input string: "1" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang

    java.lang.NumberFormatException: For input string: "1" at java.lang.NumberFormatException ...

  4. moment常用操作

    1.返回当前日期截止时的时间戳: post.createtime = moment().unix(); let stime = moment(moment.unix(moment().unix()). ...

  5. JQ(查找)

    1.由下级到上级再到下级 var aa=$("td:eq(0)").parents("tr").find("td:eq(1)"); 2.

  6. SSH框架整合中Hibernate实现Dao层常用结构

    一.疑惑 一直以来,我在使用SSH框架的时候经常会发现后者有疑虑到底使用hibernate的那种方法或者如何配置hibernate来操作数据库,经过 一段时间的学习下面我来总结一下,常用的dao层配置 ...

  7. centos下如何停止ping命令

    ctrl + c 或者 Ctrl + d(好像不行) man ping

  8. Oracle易忘知识点记录

    1.SQL Select语句完整的执行顺序: ①from子句组装来自不同数据源的数据: ②where子句基于指定的条件对记录行进行筛选: ③group by子句将数据划分为多个分组: ④使用聚集函数进 ...

  9. LeetCode Palidrome Number

    class Solution { public: bool isPalindrome(int x) { ) return false; ; int t = x; ; ) { pow *= ; cnt+ ...

  10. httpclient x-www-form-urlencoded

    1. 使用Apache httpclient提交post请求 http工具方法(需指定编码, 否则出错,这里用的UTF-8) public static String postWithParamsFo ...