.Net組件程序設計之上下文
在後續篇幅的遠程調用的文章裡有說到應用程序域,那是大粒度的控制程序集的邏輯存在,那麼想對對象的控制又由誰來做主呢?
沒錯了,就是上下文。CLR把應用程序域更細化了,在應用程序裡添置了上下文的概念,上下文是有著一套約束並且負責管理在其中的所有對象的訪問的這麼一個邏輯的存在。
舉個例子吧,雖然有點不恰當但是將就點理解吧。
比如說社會就是應用程序域,我們所住的住宅社區就是上下文的容器,社區的門衛就是上下文的行為,門衛+社區=上下文。而我們就是對象,社區的門衛對於進出社區的陌生人都會問一句:你進來找哪家?找誰?干什麼的?
而真正的上下文也是干這個的,實際要忙的多(本篇講的有點AOP的意思)
圖1
上圖中只是初步的示例結構,我們接著往下看。
在系統中,我們可以通過Context類的靜態屬性DefaultContext獲取到當前對象所在的上下文,
Context context = Context.DefaultContext;
當然也可以通過Thread類的靜態屬性CurrentContext來獲取到當前的上下文
Context context = Thread.CurrentContext;
圖2
(左端紅線開頭代表線程開始,紅線末端代表著線程介紹)
在上下文體系中,是由上下文綁定對象(ContextBoundObject)、上下文屬性(IContextAttrbitute)、上下文成員屬性(IContextProperty)和消息接收器構成的。
本篇幅只涉及到體系中的前三個知識點,也就是自定義組件服務,究竟是怎麼實現的?
在開始講之前這裡要說一下上下文和對象類型,在應用程序域裡會有一個默認的上下文,普通的對象可以任何上下文裡使用,這樣的對象被稱為上下文敏捷對象,而有的對象只能在某個特性的上下文中使用,就是繼承自ContextBoundObject類型的對象,這樣的對象被稱為 面向上下文對象。
怎麼去理解自定義組件服務呢?
1.上下文成員屬性(IContextProperty)
1 /// <summary> 2 /// 上下文成員屬性 3 /// </summary> 4 public class ContextWriterService:IContextProperty 5 { 6 7 public void Freeze(System.Runtime.Remoting.Contexts.Context newContext) 8 { 9 10 } 11 12 public bool IsNewContextOK(System.Runtime.Remoting.Contexts.Context newCtx) 13 { 14 return true; 15 } 16 17 public string Name 18 { 19 get { return "ContextService"; } 20 } 21 22 /// <summary> 23 /// 提供的服務 24 /// </summary> 25 /// <param name="meg"></param> 26 public void WriterMessage(string meg) 27 { 28 Console.WriteLine(meg); 29 } 30 }
IContextProperty接口的幾個成員: Name只讀屬性,成員屬性名稱,用作上下文成員屬性集合中的關鍵字,也可以當作是自定義服務的關鍵字和名稱。 Freeze:凍結上下文 IsNewContextOK:判斷當前上下文是否滿足需求,提供一個放棄創建上下文的機會,如果這個函數返回False的情況下。
IContextProperty類型的對象會存在於上下文的ContextProperties中,當然不是直接添加的,當我們獲取到上下文對象的時候,已經上下文對象被凍結了。
2.上下文屬性(IContextAttrbitute)
1 using System.Runtime.Remoting; 2 using System.Runtime.Remoting.Contexts; 3 using System.Runtime.Remoting.Activation; 4 5 6 [AttributeUsage(AttributeTargets.Class)] 7 public class ContextWriterAttribute :Attribute, IContextAttribute 8 { 9 10 public void GetPropertiesForNewContext(IConstructionCallMessage msg) 11 { 12 msg.ContextProperties.Add(new ContextWriterService()); 13 } 14 15 public bool IsContextOK(System.Runtime.Remoting.Contexts.Context ctx, IConstructionCallMessage msg) 16 { 17 ContextWriterService contextService = 18 ctx.GetProperty("ContextService") as ContextWriterService; 19 20 if (contextService != null) 21 { 22 return true; 23 } 24 return false; 25 } 26 }
IContextAttribute接口成員:
IsContextOK函數:在運行時調用此方法確定當前上下文是否存在需要的自定義屬性,也就是確定當前類型是否在當前上下文中激活。
GetPropertiesForNewContext:是在IsContextOK方法確定了不OK之後調用此方法,這裡的IConstructionCallMessage接口類型對象,會被傳遞到新建的上下文中,並且新建的上下文會根據IConstructionCallMessage類型當中的
ContextProperties來添加為自己的自定義服務,這也是唯一的一個機會可以添加自定義服務到上下文中。
我這裡也有一個疑問,望知道的大神給個指點,就是怎麼在當前的默認上下文中添加自定義服務?
3.上下文綁定對象(ContextBoundObject)
1 [ContextWriter()] 2 public class MyContextObject : ContextBoundObject 3 { 4 public void CallCurrentContextWriterService() 5 { 6 Context context = Thread.CurrentContext; 7 ContextWriterService contextWriterService = 8 context.GetProperty("ContextService") as ContextWriterService; 9 if (contextWriterService != null) 10 { 11 contextWriterService.WriterMessage("當前上下文ID:"+context.ContextID + "-測試信息"); 12 } 13 } 14 }
顯而易見MyContextObject是可以獲取到ContextWriterService類型,並且拿來使用的。
這些都是上下文壞境中的一部分,當然還有最重要的一部分:消息接收器,本篇幅不作介紹了,會在以後的篇幅中說到。
作者:金源
出處:http://www.cnblogs.com/jin-yuan/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面