.Net组件程序设计之上下文
.Net组件程序设计之上下文
在后续篇幅的远程调用的文章里有说到应用程序域,那是大粒度的控制程序集的逻辑存在,那么想对对象的控制又由谁来做主呢?
没错了,就是上下文。CLR把应用程序域更细化了,在应用程序里添置了上下文的概念,上下文是有着一套约束并且负责管理在其中的所有对象的访问的这么一个逻辑的存在。
举个例子吧,虽然有点不恰当但是将就点理解吧。
比如说社会就是应用程序域,我们所住的住宅社区就是上下文的容器,社区的门卫就是上下文的行为,门卫+社区=上下文。而我们就是对象,社区的门卫对于进出社区的陌生人都会问一句:你进来找哪家?找谁?干什么的?
而真正的上下文也是干这个的,实际要忙的多(本篇讲的有点AOP的意思)
图1
上图中只是初步的示例结构,我们接着往下看。
在系统中,我们可以通过Context类的静态属性DefaultContext获取到当前对象所在的上下文,
Context context = Context.DefaultContext;
当然也可以通过Thread类的静态属性CurrentContext来获取到当前的上下文
Context context = Thread.CurrentContext;
图2
(左端红线开头代表线程开始,红线末端代表着线程介绍)
在上下文体系中,是由上下文绑定对象(ContextBoundObject)、上下文属性(IContextAttrbitute)、上下文成员属性(IContextProperty)和消息接收器构成的。
本篇幅只涉及到体系中的前三个知识点,也就是自定义组件服务,究竟是怎么实现的?
在开始讲之前这里要说一下上下文和对象类型,在应用程序域里会有一个默认的上下文,普通的对象可以任何上下文里使用,这样的对象被称为上下文敏捷对象,而有的对象只能在某个特性的上下文中使用,就是继承自ContextBoundObject类型的对象,这样的对象被称为 面向上下文对象。
怎么去理解自定义组件服务呢?
1.上下文成员属性(IContextProperty)
/// <summary>
/// 上下文成员属性
/// </summary>
public class ContextWriterService:IContextProperty
{ public void Freeze(System.Runtime.Remoting.Contexts.Context newContext)
{ } public bool IsNewContextOK(System.Runtime.Remoting.Contexts.Context newCtx)
{
return true;
} public string Name
{
get { return "ContextService"; }
} /// <summary>
/// 提供的服务
/// </summary>
/// <param name="meg"></param>
public void WriterMessage(string meg)
{
Console.WriteLine(meg);
}
}
IContextProperty接口的几个成员: Name只读属性,成员属性名称,用作上下文成员属性集合中的关键字,也可以当作是自定义服务的关键字和名称。 Freeze:冻结上下文 IsNewContextOK:判断当前上下文是否满足需求,提供一个放弃创建上下文的机会,如果这个函数返回False的情况下。
IContextProperty类型的对象会存在于上下文的ContextProperties中,当然不是直接添加的,当我们获取到上下文对象的时候,已经上下文对象被冻结了。
2.上下文属性(IContextAttrbitute)
using System.Runtime.Remoting;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation; [AttributeUsage(AttributeTargets.Class)]
public class ContextWriterAttribute :Attribute, IContextAttribute
{ public void GetPropertiesForNewContext(IConstructionCallMessage msg)
{
msg.ContextProperties.Add(new ContextWriterService());
} public bool IsContextOK(System.Runtime.Remoting.Contexts.Context ctx, IConstructionCallMessage msg)
{
ContextWriterService contextService =
ctx.GetProperty("ContextService") as ContextWriterService; if (contextService != null)
{
return true;
}
return false;
}
}
IContextAttribute接口成员:
IsContextOK函数:在运行时调用此方法确定当前上下文是否存在需要的自定义属性,也就是确定当前类型是否在当前上下文中激活。
GetPropertiesForNewContext:是在IsContextOK方法确定了不OK之后调用此方法,这里的IConstructionCallMessage接口类型对象,会被传递到新建的上下文中,并且新建的上下文会根据IConstructionCallMessage类型当中的
ContextProperties来添加为自己的自定义服务,这也是唯一的一个机会可以添加自定义服务到上下文中。
我这里也有一个疑问,望知道的大神给个指点,就是怎么在当前的默认上下文中添加自定义服务?
3.上下文绑定对象(ContextBoundObject)
[ContextWriter()]
public class MyContextObject : ContextBoundObject
{
public void CallCurrentContextWriterService()
{
Context context = Thread.CurrentContext;
ContextWriterService contextWriterService =
context.GetProperty("ContextService") as ContextWriterService;
if (contextWriterService != null)
{
contextWriterService.WriterMessage("当前上下文ID:"+context.ContextID + "-测试信息");
}
}
}
显而易见MyContextObject是可以获取到ContextWriterService类型,并且拿来使用的。
这些都是上下文坏境中的一部分,当然还有最重要的一部分:消息接收器,本篇幅不作介绍了,会在以后的篇幅中说到。
作者:金源
出处:http://www.cnblogs.com/jin-yuan/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面
.Net组件程序设计之上下文的更多相关文章
- .Net组件程序设计
.Net组件程序设计之上下文 在后续篇幅的远程调用的文章里有说到应用程序域,那是大粒度的控制程序集的逻辑存在,那么想对对象的控制又由谁来做主呢?没错了,就是上下文.CLR把应用程序域更细化了,在应用程 ...
- .Net组件程序设计之远程调用(二)
.Net组件程序设计之远程调用(二) 激活模式 引用封送对象激活类型两种, 一种是客户端激活类型,一种是服务器端激活. 客户端激活对象 客户端激活方式:当客户端创建一个远程对象时,客户端得到的是一个新 ...
- .Net组件程序设计之远程调用(一)
.Net组件程序设计之远程调用(一) 1应用程序域 我们知道我们写的C#代码是在操作系统逻辑体系结构中最上层的,然而操作系统本身是不会认识C#代码的,它只认识机器代码.那我们写的程序经过编译后是编译成 ...
- .NET组件程序设计之线程、并发管理(二)
.Net组件程序设计之线程.并发管理(二) 2.同步线程 手动同步 监视器 互斥 可等待事件 同步线程 所有的.NET组件都支持在多线程的环境中运行,可以被多个线程并发访问,如果没有线程同步,这样的后 ...
- .Net组件程序设计之线程、并发管理(一)
.Net组件程序设计之线程.并发管理(一) 1.线程 线程 线程的创建 线程的阻塞 线程挂起 线程睡眠 加入线程 线程中止 现在几乎所有的应用程序都是多线程的,给用户看来就是一个应用程序界面(应用程序 ...
- .Net组件程序设计之序列化
.Net组件程序设计之序列化 自动序列化 本篇给大家讲解一下在.NET中的序列化,它的用处非常之多,特别是对于某种环境下保存某种状态是很好的方法,接下来就来看一下吧. Serializable属性 ...
- .Net组件程序设计之对象生命周期
.Net组件程序设计之对象生命周期 .NET 垃圾回收 IDisposable() Using语句 .NET 垃圾回收 是CLR管理着垃圾回收器,垃圾回收器监控着托管堆,而我们使用的对象以及系统启动是 ...
- .Net组件程序设计之异步调用
.Net组件程序设计之异步调用 说到异步调用,在脑海中首先想到就是BeginInvoke(),在一些常用对象中我们也会常常见到Invoke()和BeginInvoke(), 要想让自己的组件可以被客户 ...
- flask源码解析之上下文为什么用栈
楔子 我在之前的文章<flask源码解析之上下文>中对flask上下文流程进行了详细的说明,但是在学习的过程中我一直在思考flask上下文中为什么要使用栈完成对请求上下文和应用上下文的入栈 ...
随机推荐
- js倒计时
/** * 启动,秒杀倒计时 * totalSecond:剩余秒数 * showTime(tm):回调函数,其中tm={day:"",hour:"",min:& ...
- while 循环 。。
这是一个可以循环到天荒地老的循环: 如果while 为真就一直循环下去: count=0 while True: count+=1 if count>50 and count<60: co ...
- 模拟CSS3 多组位移运动属性的框架封装
obj是将要运动的对象,json是运动完成时的位移结果. 封装要点: 1.定时器开关flag的定义要放在for in结构的外面,否则,每遍历一次,都会定义一个 新的flag 2.if(current ...
- apache 服务器配制
简介:Apache 是世界上使用量第一的Web服务器软件,可用于linux,unix,windows等平台,尤其是对Linux支持完美 Apache的优点: 功能强大,自带很多功能模块,可根据需求编译 ...
- Linux tricks
Environment Settings Path Globally set path is in /etc/profile; or the user's .bash_profile for part ...
- JavaScript笔试必备语句【转】
1. document.write( " "); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document- >html- >(head,bod ...
- Linux上Tomcat部署JavaWeb项目
一.安装JDK 配置java的环境变量,修改/etc/profile文件:vi /etc/profile 然后按下字母i进入插入模式, shift+insert粘贴; esc退出编辑; :wq保存退出 ...
- uboot
******************************************day:2014/10/14**************************uboot************* ...
- JAVA基础整理-集合篇(一)
集合作为JAVA的基础知识,本来感觉自己理解的很清楚了,但是在最近的一次面试中还是答得不尽如人意!再次做一下整理,以便加深理解以及随时查阅. 首先,java.util包中三个重要的接口及特点:List ...
- Redis 做消息队列
一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式.利用redis这两种场景的消息队列都能够实现.定义: 生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列, ...