上一篇 中就介绍过 CreaterBuilder()方法注册了四个策略: EventBrokerStrategy,CommandStrategy,RootWorkItemInitializationStrategy ,ObjectBuiltNotificationStrategy 和三个缺省 Policy :SingletonPolicy,BuilderTraceSourcePolicy,ObjectBuiltNotificationPolicy 。
这四个策略(Strategy)都是有 SCSF(CAB) 提供的(也就是 CAB 扩展了 ObjectBuilder),三个策略中 ObjectBuiltNotificationPolicy 是 CAB 提供的。下面我们重点介绍 SCSF 提供的这些 BuilderStrategies ,对应的源代码在 Microsoft.Practices.CompositeUI.BuilderStrategies 命名空间下。
1. EventBrokerStrategy EventBrokerStrategy 应用于初始化阶段(BuilderStage.Initialization),是我们理解 SCSF EventBroker (EventPublicationAttribute 和 EventSubscriptionAttribute)的关键。

Code
1 //EventBrokerStrategy 类的 BuildUp 方法
2 public override object BuildUp(IBuilderContext context, Type t, object existing, string id)
3 {
4 WorkItem workItem = GetWorkItem(context, existing);
5
6 if (workItem != null)
7 EventInspector.Register(existing, workItem);
8
9 return base.BuildUp(context, t, existing, id);
10 }
EventBrokerStrategy 告诉 ObjectBuilder 在构建过程中调用 EventInspector.Register(existing, workItem);(在销毁过程中执行相反操作 EventInspector.Unregister(item, workItem)),EventInspector.Register(existing, workItem) 中执行两个操作:

Code
1 ProcessPublishers(item, item.GetType(), workItem, true); //class EventInspector
2 ProcessSubscribers(item, item.GetType(), workItem, true); //class EventInspector
ProcessPublishers 检查 item 中的 Event 上是否标有 EventPublicationAttribute 属性,如果有就注册到 EventTopic 的 Publication 中去:

Code
1 topic.AddPublication(item, info.Name, workItem, attr.Scope); //class EventInspector
ProcessSubscribers 检查相应的 item 中的成员上是否有 EventSubscriptionAttribute 属性,如果有就把它注册到对应得 Subscription 中去:

Code
1 topic.AddSubscription(item, info.Name, paramTypes, workItem, attr.Thread); //class EventInspector
【FLYabroad】也就是说,SCSF 启动过程中,ObjectBuilder 会到被创建的对象上去找标有 EventPublicationAttribute 和 EventSubscriptionAttribute 的事件和方法,并通过 topic, 和 PublicationScope 把对应的事件发布和接受者动态的关联起来,放到 WorkItem 的 EventTopic 集合中。 2. CommandStrategy CommandStrategy 与 EventBrokerStrategy 类似,主要负责查看构建的 item 的方法上是否有 CommandHandlerAttribute ,如果有就通过 Delegate 机制构建该对象并添加到当前 workItem 的 Commands 集合中。
3. RootWorkItemInitializationStrategy RootWorkItemInitializationStrategy 在 BuilderStage.Initialization 阶段调用,并且将 RootWorkItemInitializationCallback 绑定到了 CabApplication 的 OnRootWorkItemInitialized 方法:

Code
1 //CabApplicatioin 类中的 CreatBuilder 方法中
2 builder.Strategies.Add(new RootWorkItemInitializationStrategy(this.OnRootWorkItemInitialized), BuilderStage.Initialization);
3
整个 SCSF 应用有且只有一个 RootWorkItem ,ObjectBuilder 在创建 RootWorkItem 时通过调用 OnRootWorkItemInitialized 方法,CabApplication 中默认的 OnRootWorkItemInitialized 方法是一个空方法,子类 CabShellApplication 中重写了该方法,主要功能是将主窗体 TShell 加入到 RootWorkItem 中:

Code
1 //CabShellApplication 类重写了父类 CabApplication 空的 OnRootWorkItemInitialized 方法
2 protected sealed override void OnRootWorkItemInitialized()
3 {
4 BeforeShellCreated();
5 shell = RootWorkItem.Items.AddNew<TShell>(); //将主窗口注册到 RootWorkItem 中
6 AfterShellCreated();
7 }
8
【FLYabroad】RootWorkItemInitializationStrategy 在构建 RootWorkItem 的过程中被使用,主要任务是将主窗口 TShell 注册到 RootWorkItem 中。4. ObjectBuiltNotificationStrategy ObjectBuiltNotificationStrategy 处理初始化完成后的事情(BuilderStage.PostInitialization),主要作用是在对象创建完成后通知相应的 workItem:
ObjectBuilder 在构造 RootWorkItem 对象过程中会调用 ObjectBuiltNotificationStrategy 的 BuildUp 方法,ObjectBuiltNotificationStrategy 又会调用 ObjectBuiltNotificationPolicy(在CreateBuilder()中注册)的 policy.AddedDelegates.TryGetValue(workItem, out notification) 获取 notification 代理(ObjectBuiltNotificationPolicy.ItemNotification 类型)并执行:

Code
1 //ObjectBuiltNotificationStrategy 类中的 BuildUp 方法
2 public override object BuildUp(IBuilderContext context, Type typeToBuild, object existing, string idToBuild)
3 {
4 WorkItem workItem = context.Locator.Get<WorkItem>(new DependencyResolutionLocatorKey(typeof(WorkItem), null));
5 ObjectBuiltNotificationPolicy.ItemNotification notification;
6
7 if (policy == null)
8 policy = context.Policies.Get<ObjectBuiltNotificationPolicy>(null, null);
9
10 if (workItem != null && !Object.ReferenceEquals(workItem, existing) && policy.AddedDelegates.TryGetValue(workItem, out notification))
11 notification(existing);
12
13 return base.BuildUp(context, typeToBuild, existing, idToBuild);
14 }
15
ObjectBuiltNotificationStrategy 的 AddedDelegates 是在 WorkItem 初始化时赋值的(在InitializeFields()中注册 OnObjectAdded):

Code
1 //WorkItem 的 InitializeFields() 方法中
2 ……………………
3 ObjectBuiltNotificationPolicy policy = builder.Policies.Get<ObjectBuiltNotificationPolicy>(null, null);
4
5 if (policy != null)
6 {
7 policy.AddedDelegates[this] = new ObjectBuiltNotificationPolicy.ItemNotification(OnObjectAdded);
8 policy.RemovedDelegates[this] = new ObjectBuiltNotificationPolicy.ItemNotification(OnObjectRemoved);
9 }
10 ……………………………
11
WorkItem 中的 internal event EventHandler> ObjectAdded;是在 ManagedObjectCollection 中注册:

Code
1 //ManagedObjectCollection 的构造函数
2 public ManagedObjectCollection(ILifetimeContainer container, IReadWriteLocator locator,
3 IBuilder<BuilderStage> builder, SearchMode searchMode, IndexerCreationDelegate indexerCreationDelegate,
4 Predicate<TItem> filter, ManagedObjectCollection<TItem> parentCollection)
5 {
6 this.container = container;
7 this.locator = locator;
8 this.builder = builder;
9 this.searchMode = searchMode;
10 this.indexerCreationDelegate = indexerCreationDelegate;
11 this.filter = filter;
12 this.parentCollection = parentCollection;
13 this.workItem = locator.Get<WorkItem>(new DependencyResolutionLocatorKey(typeof(WorkItem), null));
14
15 if (this.workItem != null)
16 {
17 this.workItem.ObjectAdded += new EventHandler<DataEventArgs<object>>(WorkItem_ItemAdded);
18 this.workItem.ObjectRemoved += new EventHandler<DataEventArgs<object>>(WorkItem_ItemRemoved);
19 }
20 }
WorkItem 的 ObjectAdded 是 internal 的,只能在 CompositeUI.dll 内部使用,ManagedObjectCollection 将 WorkItem_ItemAdded() 方法绑定到了 WorkItem 的 ObjectAdded 事件,而 WorkItem_ItemAdded 方法又会触发 ManagedObjectCollection 的 Added 事件(public event EventHandler<DataEventArgs<TItem>> Added), SCSF 中 Added 事件默认没有注册,我们可以根据需要通过 ManagedObjectCollection 的 Added 事件处理对象构建完成后的事情。这又是 SCSF 的一个扩展点。
【FLYabroad】ObjectBuiltNotificationStrategy 结合 ObjectBuiltNotificationPolicy 允许我们通过在 ManagedObjectCollection 上注册 Added 事件来在对象构建完成后进行扩展处理。