您的位置:首页 > 运维架构

Context+ContextScope——这是否可以看作一种设计模式?

2012-05-02 20:43 351 查看
[code] public class ActivityContext: IDisposable

{

[ThreadStatic]

private static ActivityContext current;


 public string ActivityName{ get; private set;}

 public DateTime StartTime{ get; private set;}

 public IDictionary<string, object> Properties{ get; private set;}


 internal ActivityContext(string activityName)

{

 this.ActivityName = activityName;

 this.StartTime = DateTime.Now;

 this.Properties = new Dictionary<string, object>();

}


 public static ActivityContext Current

{

 get{ return current;}

 internal set{current = value;}

}


 public void Dispose()

{

 foreach (var property in this.Properties.Values)

{

 IDisposable disposable = property as IDisposable;

 if (null != disposable)

{

 disposable.Dispose();

}

}

}

}

[/code]
[/code]

二、ActivityContextScope

Context+ContextScope的核心不在于Context而在于ContextScope,即我们需要控制上下文的范围。对于我们的安全审核场景来说,我们需要针对用于的UI操作(比如点击某个按钮)创建ActivityContext,该上下文的生命周期仅限于针对UI事件的响应过程。为此我们创建一个ActivityContextScope类型用于创建ActivityContext并控制其生命周期。如下面的代码片断所示,ActivityContextScope除了接受一个表示创建活动的名称之外,还具有一个ContextScopeOperation枚举类型的参数。

[code]
[code] public class ActivityContextScope: IDisposable

{

 private ActivityContext current = ActivityContext.Current;

 private ActivityContext newContext;


 public ActivityContextScope(string activityName, ContextScopeOption contextScopeOption = ContextScopeOption.Required)

{

 switch (contextScopeOption)

{

 case ContextScopeOption.Required:

{

 if (null == current)

{

 ActivityContext.Current = newContext = new ActivityContext(activityName);

}

 break;

}

 case ContextScopeOption.RequiresNew:

{

 ActivityContext.Current = newContext = new ActivityContext(activityName);

 break;

}

 case ContextScopeOption.Suppress:

{

 ActivityContext.Current = null;

 break;

}

}

}


 public void Dispose()

{

 ActivityContext.Current = current;

 if (null != newContext)

{

 newContext.Dispose();

}

}

}


public enum ContextScopeOption

{

 Required,

 RequiresNew,

 Suppress

}

[/code]
[/code]
考虑在创建ActivityContextScope的时候,当前环境上下文可能已经存在,那么是重用现成的上下文还是创建新的上下文,可以通过ContextScopeOperation枚举来控制。该枚举类型的Required和RequiredNew选项分别表示重用现有上下文和创建新的上下文。另一个选项Supress表示创建一个“无环境上下文”的范围,比如TransactionScope通过类似的机制将不需要纳入事务的操作(比如Logging)从环境事务中剥离出来。基于ContextScopeOperation的ActivityContext创建机制体现在ActivityContextScope的构造函数中。ActivityContextScope实现了IDisposable接口,在实现的Dispose方法中我们将通过ActivityContext的静态属性Current表示的环境上下文恢复到ActivityContextScope创建之前的状态。

三、ActivityContextScope的使用

我们通过如下一个简单的实例来演示ActivityContextScope的使用。在Main方法中我们在一个基于“Activty1”的ActivityContextScope中调用Activty1方法。在Activty1方法中,我们在一个基于“Activty2”的ActivityContextScope中调用Activty2方法。两次创建ActivityContextScope都采用默认的ContextScopeOperation(Required)。在方法Activty2中,我们在一个基于“Activty3”的ActivityContextScope中调用Activty3方法,创建ActivityContextScope时选择RequiredNew选项。而在Activty3方法中,我们针对Supress选项创建ActivityContextScope并调用Activity4方法。方法Activty1、Activty2、Activty3和Activty4中均调用DisplayCurrentContext将当前的ActivityContext信息打印出来。

[code]
[code] class Program

{

 static void Main(string[] args)

{

 using (ActivityContextScope contextScope = new ActivityContextScope("Activty1"))

{

 Activty1();

}

}


 static void DisplayCurrentContext(string methodName)

{

 if (null != ActivityContext.Current)

{

 Console.WriteLine("{0}: Current ambient activity is{1}", methodName, ActivityContext.Current.ActivityName);

}

 else

{

 Console.WriteLine("{0}: No ambient activity.", methodName);

}

}


 private static void Activty1()

{

 DisplayCurrentContext("Activty1");

 using (ActivityContextScope contextScope = new ActivityContextScope("Activty2"))

{

 Activty2();

}

}


 private static void Activty2()

{

 DisplayCurrentContext("Activty2");

 using (ActivityContextScope contextScope = new ActivityContextScope("Activty3", ContextScopeOption.RequiresNew))

{

 Activty3();

}

}


 private static void Activty3()

{

 DisplayCurrentContext("Activty3");

 using (ActivityContextScope contextScope = new ActivityContextScope("", ContextScopeOption.Suppress))

{

 Activty4();

}

}


 private static void Activty4()

{

 DisplayCurrentContext("Activty4");

}

}

[/code]
[/code]
上面这段程序执行之后会在控制台上生成如下的输出结果,我们可以看到当前环境上下文是严格按照我们创建ActivityContextScope的方式来控制的。

[code]
[code] Activty1: Current ambient activity is Activty1

Activty2: Current ambient activity is Activty1

Activty3: Current ambient activity is Activty3

Activty4: No ambient activity.

[/code]
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: