.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组件程序设计之上下文的更多相关文章

  1. .Net组件程序设计

    .Net组件程序设计之上下文 在后续篇幅的远程调用的文章里有说到应用程序域,那是大粒度的控制程序集的逻辑存在,那么想对对象的控制又由谁来做主呢?没错了,就是上下文.CLR把应用程序域更细化了,在应用程 ...

  2. .Net组件程序设计之远程调用(二)

    .Net组件程序设计之远程调用(二) 激活模式 引用封送对象激活类型两种, 一种是客户端激活类型,一种是服务器端激活. 客户端激活对象 客户端激活方式:当客户端创建一个远程对象时,客户端得到的是一个新 ...

  3. .Net组件程序设计之远程调用(一)

    .Net组件程序设计之远程调用(一) 1应用程序域 我们知道我们写的C#代码是在操作系统逻辑体系结构中最上层的,然而操作系统本身是不会认识C#代码的,它只认识机器代码.那我们写的程序经过编译后是编译成 ...

  4. .NET组件程序设计之线程、并发管理(二)

    .Net组件程序设计之线程.并发管理(二) 2.同步线程 手动同步 监视器 互斥 可等待事件 同步线程 所有的.NET组件都支持在多线程的环境中运行,可以被多个线程并发访问,如果没有线程同步,这样的后 ...

  5. .Net组件程序设计之线程、并发管理(一)

    .Net组件程序设计之线程.并发管理(一) 1.线程 线程 线程的创建 线程的阻塞 线程挂起 线程睡眠 加入线程 线程中止 现在几乎所有的应用程序都是多线程的,给用户看来就是一个应用程序界面(应用程序 ...

  6. .Net组件程序设计之序列化

     .Net组件程序设计之序列化 自动序列化 本篇给大家讲解一下在.NET中的序列化,它的用处非常之多,特别是对于某种环境下保存某种状态是很好的方法,接下来就来看一下吧. Serializable属性 ...

  7. .Net组件程序设计之对象生命周期

    .Net组件程序设计之对象生命周期 .NET 垃圾回收 IDisposable() Using语句 .NET 垃圾回收 是CLR管理着垃圾回收器,垃圾回收器监控着托管堆,而我们使用的对象以及系统启动是 ...

  8. .Net组件程序设计之异步调用

    .Net组件程序设计之异步调用 说到异步调用,在脑海中首先想到就是BeginInvoke(),在一些常用对象中我们也会常常见到Invoke()和BeginInvoke(), 要想让自己的组件可以被客户 ...

  9. flask源码解析之上下文为什么用栈

    楔子 我在之前的文章<flask源码解析之上下文>中对flask上下文流程进行了详细的说明,但是在学习的过程中我一直在思考flask上下文中为什么要使用栈完成对请求上下文和应用上下文的入栈 ...

随机推荐

  1. 2003服务器搭建vpn

    先说下为什么会有本文,公司的git突然被防火墙屏蔽了,有些同事无奈用4g网去提交,我比较穷,1g的小水管hold不住,于是我想着用vpn.国内封杀的比较严重,免费的更是少,找朋友要了一个3小时试用的, ...

  2. IDA的脚本IDC的一个简单使用

    目的:主要是想学习一下IDA的IDC的脚本的使用.这里做了一个小的测试. 这里使用的是VS2015Community来生成文件的. 一.编写测试程序: 这里先生成我们的目标数据. 然后编写测试程序.得 ...

  3. 模拟CSS3 多组位移运动属性的框架封装

    obj是将要运动的对象,json是运动完成时的位移结果. 封装要点: 1.定时器开关flag的定义要放在for in结构的外面,否则,每遍历一次,都会定义一个 新的flag 2.if(current ...

  4. Python学习日志(一)

    Python的安装 访问http://www.python.org 点击downloads,选择Windows 我在这里选择了Latest Python 3 Release - Python 3.5. ...

  5. String.Format用法

    http://blog.csdn.net/yohop/article/details/2534907 1.作为参数   名称 说明   Format(String, Object) 将指定的 Stri ...

  6. mysql+ssh 配置(转载)

    Mysql+ssh配置 一.Linux平台间mysql+ssh配置 本机地址为:192.168.189.133 mysql服务器地址为:192.168.189.139 linux命令行下使用ssh命令 ...

  7. jsoup获取图片示例

    import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.Inp ...

  8. js 判断浏览器和ie版本号 收集

    function testB () { // body... var isOpera = !!window.opera ||!!window.opr|| navigator.userAgent.ind ...

  9. mysql问题总结

    1. You are using safe update mode and you tried to update a table without a WHERE clause that uses a ...

  10. arm,iptables: No chain/target/match by that name.

    最近由于项目需要,需要打开防火墙功能. 公司有 arm linux 3.0x86 linux 3.2x86 linux 2.4 的三个嵌入式.都需要打开防火墙功能. 执行“whereis iptabl ...