這篇文章,我們來研究一下IWizard這個介面。
一,一個用來跟蹤的介面實現LifeCycleTracerIWizard。
因為IWizard介面是Visual Studio來管理執行個體化和執行方法的,也就是說它的類型執行個體的生命週期不是我們能夠控制的,那麼我們可以換一種思路來探討這樣的生命週期,所以我定義這樣的一個IWizard實現LifeCycleTracerIWizard,用來跟蹤介面裡各個方法的執行循序,以及上下文資訊,即參數值。
LifeCycleTracerIWizard.cs的代碼如下:
1: public class LifeCycleTracerIWizard : IWizard
2: {
3: private string loggerFilePath = @"D:\LifeCycleTracerWizard.log";
4: private string safeProjectName = "[None]";
5:
6: public virtual String WizardType
7: {
8: get { return "LifeCycleTracerIWizard"; }
9: }
10:
11: private void LogWizardMethodAction(string methodAction)
12: {
13: using (StreamWriter streamWriter = new StreamWriter(loggerFilePath,true))
14: {
15: streamWriter.WriteLine(WizardType.PadRight(30) + "-" + safeProjectName.PadRight(15) + ":" + methodAction);
16: }
17: }
18:
19: #region Implementation of IWizard
20:
21: public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
22: {
23: if(replacementsDictionary != null && replacementsDictionary.ContainsKey("$safeprojectname$"))
24: {
25: safeProjectName = replacementsDictionary["$safeprojectname$"];
26: }
27:
28: LogWizardMethodAction("RunStarted : " + runKind);
29: }
30:
31: public void ProjectFinishedGenerating(Project project)
32: {
33: LogWizardMethodAction("ProjectFinishedGenerating");
34: }
35:
36: public void ProjectItemFinishedGenerating(ProjectItem projectItem)
37: {
38: LogWizardMethodAction("ProjectItemFinishedGenerating");
39: }
40:
41: public bool ShouldAddProjectItem(string filePath)
42: {
43: LogWizardMethodAction("ShouldAddProjectItem : " + filePath);
44: return true;
45: }
46:
47: public void BeforeOpeningFile(ProjectItem projectItem)
48: {
49: LogWizardMethodAction("BeforeOpeningFile");
50: }
51:
52: public void RunFinished()
53: {
54: LogWizardMethodAction("RunFinished");
55: }
56:
57: #endregion
58: }
二,用LifeCycleTracerIWizard跟蹤多項目模板的子項目。
我們修改上一篇文章中的VSTemplate-WizardExtension-FullClassName子節點值為:Ethan.Woo.TemplateWizard.LifeCycleTracerIWizard,部署後建立執行個體,查看產生的Log檔案“D:\LifeCycleTracerWizard.log”內容:
從結果可以看出以下幾點結論:
1)確實是模板中繼資料檔案中指定的Ethan.Woo.TemplateWizard.LifeCycleTracerIWizard介面實現被執行個體化了。
2)各個方法執行的順序依次為:RunStarted->ShouldAddProjectItem->ProjectFinishedGenerating->RunFinished,這裡注意一下,有兩個方法沒有執行到,ProjectItemFinishedGenerating是用於項目範本嚮導的,所以這裡肯定不會執行;BeforeOpeningFile這個方法也沒有執行,因為它在我們製作 Starter Kit的時候才會用到,所以以後會再次講到這個話題。
3)RunStarted這個方法的第三個參數是一個WizardRunKind枚舉(有三個值:AsMultiProject,AsNewItem,AsNewProject),這裡跟蹤到的值是AsNewProject,表示建立一個項目。
4)ShouldAddProjectItem這個方法執行了多次?是的,我們的項目源裡的項目包含了多個子檔案,所以,這裡明顯是在模板執行個體化階段,添加每個子檔案時調用的,而且它有一個Boolean傳回值,表示十分要添加當前的子檔案到項目執行個體中。
三,用多個IWizard介面實現跟蹤多項目模板的子項目。
先摘一段來自MSDN的原文:
Visual Studio supports chaining, which enables a single template to have multiple IWizard implementations. These implementations are called sequentially, so you can create templates that have rich, flexible functionality.
A Microsoft-implemented VsTemplate wizard is invoked to process a template by reading its .vstemplate file. A VsTemplate can list one or more assemblies that have an IWizard implementation that will be called to participate in processing the template. To take advantage of chaining, all the wizards must be listed in the template's .xml file in the order in which they should be called.
意思是說:Visual Studio支援單模板的IWizard介面實現的串聯,並且是順序執行的,還能推斷出VSTemplate這個節點可以包含多個WizardExtension的設定,實現這樣的一種串聯。
這裡我們新定義一個ChainingLifeCycleTracerIWizard介面實現,繼承之前的LifeCycleTracerIWizard;
1: public class ChainingLifeCycleTracerIWizard : LifeCycleTracerIWizard
2: {
3: public override string WizardType
4: {
5: get
6: {
7: return "ChainingLifeCycleTracerIWizard";
8: }
9: }
10: }
然後,我們將這個ChainingLifeCycleTracerIWizard和之前的LifeCycleTracerIWizard一起串聯到WebClient項目的模板中,當然了,還是通過模板中繼資料檔案,注意這裡的聲明的順序;
1: <VSTemplate xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Version="3.0.0" Type="Project">
2: 。。。此處省略。。。
3: <WizardExtension>
4: <Assembly>Ethan.Woo.TemplateWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e82b5e824e88ddd5</Assembly>
5: <FullClassName>Ethan.Woo.TemplateWizard.LifeCycleTracerIWizard</FullClassName>
6: </WizardExtension>
7: <WizardExtension>
8: <Assembly>Ethan.Woo.TemplateWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e82b5e824e88ddd5</Assembly>
9: <FullClassName>Ethan.Woo.TemplateWizard.ChainingLifeCycleTracerIWizard</FullClassName>
10: </WizardExtension>
11: </VSTemplate>
最後我們看看Log檔案“D:\LifeCycleTracerWizard.log”內容:
是不是很有意思,都執行了一遍哦,不用解釋了吧。
摘自:http://www.ethan-woo.com/post/2011/05/03/Deep-into-IWizard-First.aspx