First Step – Create/Compile a policy

 

Basic setup:

We will need to create a ClassLibrary (I used a C# library for this example).  Once the project is created, we need to add a few references:  System.Windows.Forms and Microsoft.VisualStudio.Hatteras.Client.dll (name will be changing shortly).  Now that our references are setup, make sure your class implements the correct interfaces:

 

public class NoTabsPolicy : IPolicyDefinition, IPolicyEvaluation

 

One more quick class definition step to take; this class must be Serializable – the serialized object is stored on the server, so each time the client needs to use this policy, the policy is de-serialized.  The only exception to this is when it is being configured or installed; the object is constructed and when the user saves the policy the serialized object is sent to server.  Make class serializable:

 

[Serializable]

public class NoTabsPolicy : IPolicyDefinition, IPolicyEvaluation

 

For this example, I am going to store my strings in an internal class – these should be pulled out and placed in a resource file (that is skipped here to focus on policy creation).  Here are the strings defined:

 

public class Strings

{

       public static string policyType = "No Tabs Policy";

       public static string policyDescription = "This policy ensure that there are no tabs embedded into the source control of particular file types.";

       public static string policyInstallationInstructions = "Please see http://instructions";

       public static string policyTypeDescription = "Type Description";

       public static string policyDisposedMessage = "Policy Object has been disposed.";

       public static string policyHelp = "Help for policy";

       public static string activateMessage = "Tabs found in: {0}";

}

 

For the base skeleton, we need no code in the constructor.

 

IPolicyDefinition implementation:

public String Type

{

       get

       {

             return Strings.policyType;

       }

}

 

public String Description

{

       get

       {

             return Strings.policyDescription;

       }

}

 

public String InstallationInstructions

{

       get

       {

              return Strings.policyInstallationInstructions;

       }

}

 

public String TypeDescription

{

       get

       {

              return Strings.policyTypeDescription;

       }

}

 

public bool Edit(System.Windows.Forms.IWin32Window parent, System.IServiceProvider serviceProvider)

{

       return true;

}

 

 

Now we can implement the IPolicyEvaluation:

public void DisplayHelp(Microsoft.VisualStudio.Hatteras.Client.PolicyFailure failure)

{

       MessageBox.Show(Strings.policyHelp);

}

 

public void Initialize(IPendingCheckin pendingCheckin)

{

}

 

public void Dispose()

{

       policyDisposed = true;

}

 

public PolicyFailure[] Evaluate()

{

       if (policyDisposed)

       {

             throw new ObjectDisposedException(Strings.policyType, Strings.policyDisposedMessage);

       }

 

       return null;

}

 

public void Activate(PolicyFailure failure)

{

       return;

}

 

Finally, we need some non-serialized data.

[NonSerialized]

private bool policyDisposed = false;

 

public event PolicyStateChangedHandler PolicyStateChanged;

 

The PolicyStateChanged event is part of the IPolicyEvaluation interface; just defining it here allows policy to compile (with a warning, but we will take care of that later).

 

Now we have a policy; the only problem is that the policy will never fail due to the return null in Evaluate().  The evaluate method is called when the user attempts to checkin source code.  The Activate() method is called when a user double-clicks on a failed policy in the toolwindow – we will add more information here as this policy matures.

 

Stay tuned… next we will add more functionality to this skeleton policy.