`
wzhelp
  • 浏览: 46397 次
  • 性别: Icon_minigender_1
  • 来自: 石家庄
社区版块
存档分类
最新评论

.net 上下文

    博客分类:
  • Net
阅读更多
22.15 .NET上下文
22.15.1 简介
我们已经看到AppDomain能够在运行期间实现类 型、安全和异常层面的隔离。然而还存在着比AppDomain更加细粒度的用于存储.NET对象的实体。一个.NET AppDomain能够包含多个这种叫做.NET上下文的实体。在本章,只要不会与COM+上下文概念发生混淆,我们就把它们称作上下文,这两个概念是完 全不同的(COM+上下文在8.8节介绍)。某些作者使用托管上下文(managed context)或者执行上下文(execution context)来指代.NET上下文,而非托管上下文则指代COM+上下文。所有.NET对象都存在于上下文中,每个AppDomain中至少存在一个 上下文。这个上下文称为AppDomain的默认上下文,它在AppDomain创建的时候就创建了。图22-7总结了它们之间的关系。

图22-7 进程、AppDomain和上下文
上下文的概念使得拦截对象的调用成为可能。拦截调用意味着我们可以对每个输入或输出参数做一个或多个转换。这些转换是通过消息接收器来完成的。这样做主要是为了让客户端在调用对象的方法时不会察觉到调用被拦截了以及在方法处理的前后对参数做了转换。
22.15.2 上下文绑定和上下文灵活对象
根 据上一节的内容,上下文可以看作AppDomain中一个包含对象和消息接收器的区域。对上下文里的对象的调用会转换成可以被消息接收器拦截和处理的消 息。我们知道要把调用转换成消息,必须通过透明代理这个中介。而且,仅当对象是MarshalByRefObject的子类的实例并被其所在的 AppDomain以外的实体调用时,CLR才会为它创建透明代理。这里,我们希望对所有调用使用消息接收器机制,即使是那些同一个AppDomain中 的实体所执行的调用。这个时候我们就需要用到System.ContextBoundObject类了。继承自ContextBoundObject的类 的实例同样仅能由透明代理访问。此时,甚至这个类的方法中所使用的this引用也是透明代理而不是对这个对象的直接引用。让 ContextBoundObject类继承自MarshalByRefObject是合理的,因为它很好地强调了该类的特性——它告诉CLR这个类将会 通过透明代理使用。
ContextBoundObject的子类的实例被视为是上下文绑定的。没有继承自 ContextBoundObject的类的实例则被视为是上下文灵活的。上下文绑定的对象永远在其上下文中执行。只要不是远程对象,上下文灵活的对象总 是在执行这个调用的上下文中执行。图22-8说明了以上内容。

图22-8 上下文绑定的对象与上下文灵活的对象
22.15.3 上下文attribute和上下文属性
下面我们将介绍用于在上下文层面注入消息接收器的技术。首先介绍上下文attribute和上下文属性的概念。
1.上下文attribute
上 下文attribute是指应用在上下文绑定类上的.NET attribute。上下文attribute类实现了System. Runtime.Remoting.Contexts.IContextAttribute接口。上下文绑定的类可以应用多个上下文attribute。 在这个类的对象创建期间,这个类的每个上下文attribute都要判断这个对象的创建者所在的上下文是否适用。下面这个方法执行了这个操作。

只要其中一个上下文attribute返回false,CLR就必须创建一个新的上下文来容纳这个新的对象。这样,每个上下文attribute都可以在这个新的上下文中注入一个或多个上下文属性。这些注入可以通过以下方法实现。

2.上下文属性
上 下文属性是实现System.Runtime.Remoting.Contexts.IContextProperty接口的类的实例。每个上下文可以包 含多个属性。上下文属性在上下文创建的时候通过上下文attribute注入。一旦每个上下文attribute都注入了它的属性,那么就会为每个属性调 用下面的方法。此后就无法在这个上下文中注入另外的属性了。

然后,CLR通过调用下面的方法判断新的上下文能否满足每个属性。

每个上下文属性都有一个通过Name属性定义的名称,如下所示:

上下文中承载的对象的方法可以通过调用下面的方法访问上下文属性。

这一点很有意思,上下文中的对象通过它们所在的上下文的属性可以共享信息并访问服务。不过,上下文属性的主要作用并不在于此。上下文属性的主要作用在于向相关上下文中的消息接收器区域注入消息接收器。
对 消息接收器区域的介绍是下一小节的主题。在此之前,让我们先通过示例演示上下文attribute和上下文属性的概念。对于那些读过信道那节的读者,上下 文attribute的角色相当于在信道中注入提供程序的配置文件。同样地,上下文属性的角色相当于消息接收器提供程序。
3.使用上下文attribute和属性的示例
下 面的程序定义了LogContextAttribute类和LogContextProperty类。应用了LogContext- Attribute的类的所有实例都将承载在具有LogContextProperty类型的属性的上下文中。于是,该实例就可以访问这个属性提供的服务 了。这个服务允许通过调用LogContextProperty. Log(string)方法向文件写入一个字符串。文件名是LogContextAttribute的参数。这样,我们就可以让每个类都拥有一个配置文 件。当应用了LogContextAttribute的类的新实例创建好后,boolLogContextAttribute. IsContextOK(Context)方法将判断调用构造函数的实体所在的上下文是否包含带有相同文件名的LogContextAttribute的 实例。如果不是,则会创建一个新的上下文。LogContextAttribute.GetPro- pertiesForNewContext(IConstructionCallMessage ctor)方法创建一个LogContextProperty的实例。在这个方法返回时,CLR自动把新的属性注入新的上下文。下面是程序的代码。
例22-33



该程序输出:

obj1和obj3这两个对象位于同一个上下文中,因为obj3是在obj1所在的上下文中创建的。
22.15.4 消息接收器区域
消 息接收器区域有以下四种:服务器区域、对象区域、信使区域和客户端区域。要理解区域概念,必须考虑上下文绑定的对象是否被位于另一个上下文中的实体调用。 这个实体可以是一个静态方法或者另一个对象。在我们关于区域的讨论中,我们把这个实体所在的上下文称为调用方上下文,而把被调用对象所在的上下文称为目标 上下文。目标上下文中的每个属性都可以在这些区域中注入消息接收器。
• 注入服务器区域的消息接收器拦截所有从另一个上下文发往目标上下文中所有对象的调用消息。于是,每个目标上下文有一个服务器区域。
• 注入对象区域的消息接收器拦截所有从另一个上下文发往目标对象中特定对象的调用消息。于是,上下文中每个对象会有一个对象上下文。
• 注 入信使区域的消息接收器拦截所有从另一个上下文发往目标对象中特定对象的调用消息。于是,上下文中的每个对象都有一个信使区域。信使区域和对象区域的不同 点是信使区域位于调用方上下文而不是包含对象的目标上下文。我们使用信使区域把调用方上下文的信息传递给目标上下文的消息接收器。
• 注入客户端区域的消息接收器拦截所有从目标上下文发往位于其他上下文的对象的调用消息。于是,每个目标上下文有一个客户端区域。
图22-9说明了区域的概念。目标上下文包含名为OBJ1和OBJ2的两个对象。我们选择在目标上下文中放置两个对象而不是一个是为了更好地说明对象区域和信使区域是在对象层面与消息的拦截关联起来的,而服务器区域和客户端区域则是在上下文层面与消息的拦截关联起来的。
我 们在每个区域中放置了两个自定义消息接收器是为了更好地说明一个区域能包含零个、一个或多个消息接收器。具体地说,所有自定义消息接收器都通过目标上下文 的属性注入区域,即使这个区域不属于目标上下文。因为上下文属性类是可以自定义的,所以我们可以选择哪个区域必须注入消息接收器。
你可能注意到,每个区域包含一个用于通知CLR退出区域的系统终结器接收器,不过不需要太在意它。
当调用方上下文和目标上下文处在同一个AppDomain中时,CLR会使用mscorlib.dll中CrossContextChannel内部类的实例作为信道。这个实例会使得当前线程的Context属性发生切换。图22-9展示了这些实例。

图22-9 上下文和区域
22.15.5 使用区域的示例
我们想通过例22-34的程序说明以下内容。
• 自 定义上下文attribute(CustomDisplayContextAttribute类)的代码在上下文中注入了自定义上下文属性 (CustomDisplayContextProperty类)。这个上下文属性在目标上下文的对象区域、服务器区域和客户端区域以及调用方上下文的信 使区域中注入了自定义消息接收器(CustomDisplayMessageSink类)。
• 消息接收器的行为可以通过传递给上下文attribute的参数修改。这里,这个参数是一个布尔值,它指示消息接收器是否必须在控制台上输出某些东西。
• 消 息接收器通过上下文属性注入这四个区域。CustomDisplayContextAttribute上下文attribute确保为Foo类的每个实例 创建上下文。我们首先创建Foo的实例,然后我们在这个实例上调用一个方法并穿越信使区域、服务器区域和对象区域的消息接收器。要穿越客户端区域的消息接 收器,我们创建了Foo的第二个实例,然后让第一个实例调用它。于是,这里有了三个上下文:执行Main()方法的上下文(ContextID = 0)、包含Foo的第一个实例的上下文(ContextID = 1)和包含Foo的第二个实例的上下文(ContextID = 2)。
• 上下文内部调用不会触发所有这些消息接收器的调用。这在Foo的第一个实例调用自身时可以看到。
• 在区域(这里是客户端区域)中注入了多个消息接收器。
• CLR在区域中注入消息接收器的时间。我们很清楚的看到这个时间依赖于区域的类型。
程序如下:
例22-34






执行程序后的输出如下所示。
 
 
22.15.6 调用上下文
可 以在运行在调用方上下文中的消息接收器与运行在目标上下文中的消息接收器之间传递信息。我们使用这个技术主要是为了把调用方上下文的信息传递给目标上下文 (例如调用方上下文支持某些属性)。我们把这项功能称为调用上下文。尽管它的名字中含有“上下文”这三个字,但是这项功能可以用在任何消息接收器中,包括 那些不在上下文中的。
为此,必须首先定义一个实现 System.Runtime.Remoting.Messaging.ILogicalThreadAffinative接口的类来描述要传递的信息。 在运行在调用方上下文(在信使区域或者客户端区域里)中的消息接收器的代码中,我们必须把这个类的实例附加到表示调用的消息上。在运行在目标上下文(在对 象区域或者服务器区域里)中的消息接收器的代码中,必须把这个类的实例从表示调用的消息中分离出来。这些操作是通过 IMethodMessage.LogicalCallContext属性完成的。
下面的代码演示如何运用该技术。
例22-35


我 们在前一节看到,在客户端区域和信使区域中注入消息接收器是发生在调用对象的构造函数之后。客户端区域和信使区域中的消息接收器无法把信息附加到表示构造 函数调用的消息上,而服务器区域的消息接收器却可能依然试图从表示构造函数调用的消息中分离出这个信息。在这种情况下,我们可以在上下文 attribute的GetPropertiesForNewContext()方法中附加这个信息。
例22-36

22.16 小结
22.16.1 激活对象的四种方式
我们已经看到,激活对象的方式有四种:WKO single-call模式、WKO singleton模式、CAO和对象发布。下面这张表总结了这些模式之间的主要差异。

22.16.2 截获消息
我们用了本章的一半专门来介绍如何拦截表示调用的消息以及为何这样做。图22-10简要总结了各种可能的拦截层面。

图22-10 拦截消息

分享到:
评论

相关推荐

    NET组件程序设计 第2版中文版.part3.rar )

    .NET上下文 自定义组件服务 第12章:安全 .NET安全架构 配置权限 编程式安全 Visual Studio 2005与安全 基于主体的安全 其他安全问题 附录A:基于接口的Web服务 附录B:统一Windows Forms和ASP.NET安全 附录C:反射...

    【objectarx.net】上下文菜单和对象上下文菜单

    本工程在objectarx2020下测试通过,如要在其他版本的sdk下使用,需要修改工程的引用文件 编译方法: 1、将解压后的文件夹放到objectarx2020 文件夹 内samples\dotNet 目录下,如G:\mywork\my-object-arx\samples\...

    Tarife.net简单搜索「Tarife.net Simple Search」-crx插件

    当在页面上标记文本时,该扩展在上下文菜单中添加新条目。... 怎么做: ... - 选择tarife.net上下文项目 标记的文本将被发送到www.tarife.net搜索,并将结果显示在一个新标签中。 支持语言:Deutsch,English

    Tarife.net Simple Search-crx插件

    语言:Deutsch,English ... 当在页面上标记文本时,此扩展名将在上...怎么做:-在任何网站上标记文本(大部分为一个单词)-单击鼠标右键-选择tarife.net上下文项标记的文本将发送到www.tarife.net搜索并以新标签页给您。

    如何为控件添加上下文菜单(visual studio C++源代码编写).net

    如何为控件添加上下文菜单(visual studio C++源代码编写).net

    .NET面向上下文、AOP架构模式(实现)

    在本人的.NET面向上下文、AOP架构模式(概述)一文中,我们大概了解了上下文如何辅助对象在运行时的管理。在很多时候我们急需在运行时能把对象控制在一定的逻辑范围内,在必要的时候能让他们体现出集中化的概念,如...

    【ASP.NET编程知识】.NET Core 3.0 可回收程序集加载上下文的实现.docx

    【ASP.NET编程知识】.NET Core 3.0 可回收程序集加载上下文的实现.docx

    C#综合细说进程、应用程序域与上下文

    本文主要是介绍进程(Process)、应用程序域(AppDomain)、.NET上下文(Context)的概念与操作。虽然在一般的开发当中这三者并不常用,但熟悉三者的关系,深入了解其作用,对提高系统的性能有莫大的帮助。在本篇...

    spring.net中文手册在线版

    19.2.自动装载应用程序上下文和应用程序上下文嵌套 19.2.1. 配置 19.2.2.上下文嵌套 19.3.为ASP.NET页面进行依赖注入 19.3.1.为Web控件进行依赖注入 19.4.Master Page 19.4.1.将子页面与Master Page关联 19.5.双向...

    Versioner:Versioner 是一个实用程序库,用于为 .NET 应用程序提供版本和依赖项的概念,并在它们之上实现常见的操作

    Versioner 是作为可移植类库实现的,应该可以在任何 .NET 上下文中使用。安装版本。 要安装,请在包管理器控制台中运行以下命令: PM> Install-Package EdCanHack.Versioner用法您的消费应用程序只需要实现...

    .net Reflector 9.0附注册机

    .NET Reflector是一个.NET工具。.NET开发人员用它来反编译和观察内在内容,了解...上下文相关的文档视图 找出虚拟方法重写 代码URL支持——在浏览器中导航至代码:/ / mscor lib / system.object 挖掘程序集中的资源

    DbHelperSQL类文件(asp.net最基本方法)

    DbHelperSQL类,包括对数据库操作的所有方法,如公用方法、执行简单SQL语句、执行带参数的SQL语句、存储过程操作等。

    ACMESharpCore:NET标准的ACME v2客户端库(让我们加密)

    ACMESharp核心 ...测验 组件/测试类型 Linux 视窗 基本单元测试 SimplePKI单元测试 MockServer单位苔丝 整合测试 ...该库最初是ACMESharp客户端库从.NET Framework到.NET Standard... 如果您有兴趣在.NET上下文中使用Let'

    ASP.NET常见问题集锦.zip

    关于上下文.doc 创建可分页、可排序的 DataGrid.doc 创建用于 ASP.NET 的分页程序控件.doc 创建用于ASP.NET的分页控件.txt 利用 ASP.NET 创建多页自定义报表.doc 利用属性扩展元数据.doc 在 ASP.NET 中实现...

    企业微信开发.net版[盛派微信SDK]

    微信公众平台SDK Senparc.Weixin for C#,...已经支持用户会话上下文(解决服务器无法使用Session处理用户信息的问题)。 已经全面支持微信公众号、企业号、开放平台的最新API。 已经支持分布式缓存及缓存策略扩展。

    rust-execution-context:为Rust实现.NET启发的执行上下文

    这实现了.NET启发的执行上下文。 这样的想法是,如果可以证明这样的事情表现合理,它可能会成为核心语言概念。 什么是执行上下文? 执行上下文是逻辑调用流的容器。 这个想法是,遵循相同执行流程的任何代码都可以...

    .NET Reflector 8.1{内含破解教程和注册机}

    .NET Reflector介绍: .NET Reflector是一个.NET工具,30多万专业的.NET开发人员用...上下文相关的文档视图 找出虚拟方法重写 代码URL支持——在浏览器中导航至代码:/ / mscor lib / system.object 挖掘程序集中的资源

Global site tag (gtag.js) - Google Analytics