Customizing Versus Extending


Customizing Versus Extending

What's the difference between customizing and extending? Both terms mean “changing or altering” the existing software in some way. Customizing means using the mechanisms that exist out of the box to tweak Team System, whereas extending typically involves writing code and building and registering assemblies. Customizing, therefore, can be thought of as being a little easier to accomplish by an audience that is a little less focused on building tools, where extending requires more time, and effort, by an audience that is more comfortable with application programming interfaces (APIs) and software development kits (SDKs). These are just general guidelines, however.

Table 9-1 shows some of the other differences.
Table 9.1: Customizing versus Extending

Customizing

Extending

What is it?

Tailoring Team System and/or Team Foundation Server to your environment

Adding new functionality to Team System and/or Team Foundation Server

Who performs it?

Team System users, project managers, developer leads

Internal IT/developer, ISV (independent software vendor) partners

Why is it performed?

To adjust basic capabilities to suit your team's needs

To deeply integrate complementary features

How is it performed?

Configuration through user interface (UI), authoring XML files, or possibly some light automation

Web service development, database development, Visual Studio Integrator Program (VSIP) integration, and so on

First, we'll take a close look at how you can customize Team System to match your own team's development processes. Then we'll take a quick look at how Team System can be extended to integrate custom tools from Microsoft partners.

Customizing Team System

Many areas can be customized. One could argue that by selecting a different methodology template when you create a new team project, you have customized the process. I will ignore those kinds of settings and properties and focus instead on some not-so-obvious areas that can be customized, specifically the following:

  • Process Guidance.

    Modify existing template or documentation (or build your own).

  • Work Item Types.

    Modify existing work item types to add new fields, ToolTips, or drop-down lists.

  • Version Control.

    Select version control policies.

  • Reporting.

    Modify existing reports or add your own.

  • Project Portal.

    Add new documents and lists, and change the layout.

Customizing Process Templates

Team System uses process templates to automate the configuration of new Team System projects. Simply put, a process template tells Team System step by step exactly how to set up a new project. In a very direct way, the process template defines the methodology for a project by specifying which process tools will be used and how those tools will be configured for the project. The process template even installs the project's process guidance documentation.

The truly marvelous thing about a process template is that a team can take an existing template and customize it without having to do any programming or use any proprietary tools. This flexibility enables the team to build its own processes into Team System and then improve those processes over time based on lessons learned.

Team System comes with two process templates: Microsoft Solutions Framework (MSF) for Agile Software Development and MSF for Capability Maturity Modeling Integration (CMMI) Process Improvement. These templates can be used as-is or customized as needed.

Let's explore the process template for MSF for Agile Software Development. If you launch Microsoft Visual Studio 2005, connect to your Team Foundation Server, and then bring up the Process Template Manager (shown in Figure 9-1), located in the Team menu under Team Foundation Server Settings, you see that you can import and export process templates. After they are exported, you can browse the directory containing the process template to see the structure. Typically, there are many folders, containing many files. These folders and files can be altered, and then the Process Template Manager can be used to import new or changed templates back into Team System.

figure 9-1 process template manager

Figure 9-1 Process Template Manager

Figure 9-2 shows the structure of the process template for MSF for Agile Software Development. Notice that there are XML files throughout the template. These files are called Process Definition Files. These files tell Team System which Process Template Plug-Ins to use and also define the sequence of tasks the Process Template Plug-Ins should perform. Two important definition files are the MetaData.xml and MethodologyTemplate.xml files. If you want to create a new template, rather than just edit an existing one, you need to alter the contents of these two files, changing the names and descriptions. The subdirectories contain other tool-specific files, most of which have been omitted from the figure for clarity.

figure 9-2 process template--msf for agile software development

Figure 9-2 Process template—MSF for Agile Software Development

Process Template Plug-Ins are components that Team System uses to create a new team project. Each plug-in plays a specific part in the setup process. Microsoft provides six plug-ins with Visual Studio 2005 Team System, as shown in Table 9-2.

Table 9.2: Process Template Plug-Ins

Plug-In Name

Description

Classification Structure System (CSS)

Defines a team project's initial iterations, organization units, components, or feature areas

Group Security Service (GSS)

Defines a team project's initial security groups and their permissions

Microsoft Windows® SharePoint® Services (WSS)

Defines the project portal for the team based on a WSS site template; also defines template files and process guidance

Currituck

Defines a team project's initial work item types, queries, and work item instances

Rosetta

Defines a team project's initial reports

Source Code Control (SCC)

Defines a team project's initial version control security permissions and check-in notes

Let's take a behind-the-scenes tour of the process template in action. It all starts when a user, typically the team lead, launches the New Team Project Wizard in Visual Studio. The wizard asks for the project name and description. Then it asks the user to select a process template. Team System starts by examining the process definition file called MethodologyTemplate.xml in the root directory of the selected process template. This is the main process definition file, and it looks something like this:

<methodology>    <metadata>      <name>MSF for Agile Software Development</name>       <description>Choose the MSF Agile process for projects   with short lifecycles...</description>      <plugins>        <plugin name="Microsoft.Pcw.Css" wizardPage="false"/>        <plugin name="Microsoft.Pcw.Rosetta" wizardPage="false"/>        <plugin name="Microsoft.Pcw.wss" wizardPage="true"/>        <plugin name="Microsoft.Pcw.gss" wizardPage="false"/>        <plugin name="Microsoft.Pcw.currituck" wizardPage="false"/>        <plugin name="Microsoft.Pcw.scc" wizardPage="true"/>      </plugins>    </metadata>    <groups>      <group         description="Structure definition for the project."        completionMessage="Project Structure uploaded."        failureMessage="Project Structure upload failed.">        <dependencies>        </dependencies>        <taskList filename="Css\CssTasks.xml"/>      </group>      <group          description="Create Groups and Permissions."         completionMessage="Groups and Permissions created."         failureMessage="Groups and Permissions failed.">        <dependencies>          <dependency group />         </dependencies>        <taskList filename="Gss\GssTasks.xml" />       </group>      <group         description="Creating project Site"        completionMessage="Project site created."        failureMessage="Project site creation failed.">        <dependencies>          <dependency group/>          <dependency group/>          <dependency group />        </dependencies>        <taskList filename="Wss\WssTasks.xml"/>      </group>      <group       description="Project reports uploading."      completionMessage="Project reports uploaded."      failureMessage="Project reports upload failed.">      <dependencies>        <dependency group/>        <dependency group/>      </dependencies>      <taskList filename="Reports\ReportsTasks.xml"/>    </group>      <group       description="Work item definitons uploading."      completionMessage="Work item definitons uploaded."      failureMessage="Work item definitons creation failed.">      <dependencies>        <dependency group/>        <dependency group/>      </dependencies>      <taskList filename="Currituck\CurrituckTasks.xml"/>    </group>    <group       description="Creating version control."      completionMessage="Version control created."      failureMessage="Version control creation failed.">      <dependencies>        <dependency group/>        <dependency group />      </dependencies>      <taskList filename="Scc\SccTasks.xml"/>    </group>    </groups>  </methodology>

The name and description sections are self-explanatory. The plug-in section lists the process template plug-ins that will be used to create the new team project. The groups section contains a list of task groups that must run. The group section for WSS (group id=“WSS”) is the task group for the WSS plug-in, which creates the Web portal for the new team project. Notice that the group section contains a description, completion message, and the failure message that the wizard uses when it runs the WSS task group. The dependencies list indicates that the CSS, Currituck, and SCC task groups must finish their tasks successfully before the WSS task group can start. Finally, the taskList section contains the name of the XML file containing the task list for the WSS task group.

Generally, there is one task group per plug-in, but Team System does not impose this limitation. It's possible to use multiple plug-ins within one task group, but that can get confusing and should be avoided if possible. Also, there need not be a task group for every plug-in. In fact, the CSS plug-in for Classification Structure Service is the only one required by the process template—all the other plug-ins are optional.

NOTE
The file MetaData.xml in the process template's root directory is simply a copy of all the metadata elements (name, description, plug-ins) from the MethodologyTemplate.xml file. MethodologyTemplate.xml and all other folders are compressed into a single binary object and stored in the Team Foundation Server database. MetaData.xml is stored in a separate field so that the New Team Project Wizard and Process Template Manager can retrieve basic process template attributes without unzipping the binary object.

Back at the New Team Project Wizard, each plug-in listed in MethodologyTemplate.xml is given an opportunity to collect configuration settings from the user by displaying a data-entry screen in the wizard. When the user clicks the wizard's Finish button, Team System starts the process to create the new team project.

Team System processes the task groups one at a time. The order in which they are processed is based on the dependencies in the task group definitions. When a task group is invoked, Team System examines the task list file associated with the task group. Here is the task list for Currituck, the process template plug-in for work item tracking.

<tasks>    <task            name="WorkItemType Definitions"      plugin="Microsoft.Pcw.Currituck"      completionMessage="WorkItemTypes created"               completionDescription = "Processing the WorkItemTypes used by Currituck">      <taskXml>        <WORKITEMTYPES>          <WORKITEMTYPE fileName="Currituck\TypeDefinitions\Bug.xml"/>          <WORKITEMTYPE fileName="Currituck\TypeDefinitions\Task.xml"/>          <WORKITEMTYPE fileName="Currituck\TypeDefinitions\Qos.xml"/>          <WORKITEMTYPE fileName="Currituck\TypeDefinitions\Scenario.xml"/>        </WORKITEMTYPES>      </taskXml>    </task>    <task            name="WorkItems"      plugin="Microsoft.Pcw.Currituck"      completionMessage="WorkItems uploaded"      completionDescription = "Processing the actual WorkItems used by Currituck">      <dependencies>        <dependency task />      </dependencies>      <taskXml>        <WORKITEMS>          <WI type="Task">            <FIELD name="Title" value="Setup: Set Permissions" />            <FIELD name="ShortDescription" value="" />            <FIELD name="Iteration Path" value="Iteration 0" />            <FIELD name="State" value="Active" />            <FIELD name="Reason" value="New" />            <FIELD name="Issue2" value="No" />            <FIELD name="Scheduled" value="No" />            <FIELD name="Summary Task" value="No" />            <FIELD name="Exit Criteria" value="Yes" />          </WI>  ...          <WI type="Task">            <FIELD name="Title" value="Create Project Checklist Items" />            <FIELD name="ShortDescription" value="" />            <FIELD name="Iteration Path" value="Iteration 1" />            <FIELD name="State" value="Active" />            <FIELD name="Reason" value="New" />            <FIELD name="Issue2" value="No" />            <FIELD name="Scheduled" value="No" />            <FIELD name="Summary Task" value="No" />            <FIELD name="Exit Criteria" value="Yes" />          </WI>        </WORKITEMS>      </taskXml>    </task>    <task            name="Stored Query Definitions"      plugin="Microsoft.Pcw.Currituck"      completionMessage="Queries uploaded"      completionDescription = "Processing the stored queries used by Currituck">      <dependencies>        <dependency task />        <dependency task />      </dependencies>      <taskXml>        <QUERIES>          <Query             name="All Scenarios"             fileName="AllScenarios.wiq" />  ...          <Query             name="All My Team Project Work Items"             fileName="MyWorkItemsAllTeamProjects.wiq" />        </QUERIES>      </taskXml>    </task>  </tasks>

This task list file contains three tasks: Work Item Definitions, Work Items, and Stored Query Definitions. Note that each task section has an ID field, which uniquely identifies the task within the task group. It also has name, completionMessage, and completionDescription sections that are used by the wizard. Each task section also specifies the plug-in to use. All the tasks in this task list use the Currituck plug-in. The dependencies section for each task indicates the tasks that must complete before that task can be performed. Looking at the Stored Query Definitions task, you can see that the other two tasks must be completed first.

The structure of the taskXml section is “owned” by the plug-in, and it varies from task to task. For instance, the taskXml section for the Work Item Definitions task contains the list of work item definitions, while the taskXml section for the Stored Query Definitions task contains a list of query definitions.

By editing the MethodologyTemplate.xml file and the associated task list files, you can customize every aspect of the project-creation process. Follow these best practices when creating your own custom process template:

  • Always start by exporting and editing an existing template. Creating a process template from scratch is very difficult.

  • Make small incremental changes to the template, and then test it to make sure it is working properly.

  • List your tasks in each XML process definition file in the same order as their dependencies. This will make it easier to eliminate any dependency problems, and it will be easier to read.

  • Import your new process template into a test environment, and make sure it's working properly before importing it into your production environment.

Customizing Process Guidance Documentation

The MSF for Agile Software Development process template automatically creates a Windows SharePoint Services Web site containing, among other things, the process guidance documentation. You might want to edit this documentation to more accurately reflect your development process. The process guidance Web pages are generated from an XML file call ProcessGuidance.xml, which is transformed to HTML for display in a Web browser. You can edit this document with an XML editor like the one in Visual Studio, but there's an easier way. The tool of choice in this case is InfoPath®. (See Figure 9-3.) It presents the document as an intuitive data entry form that's easy to edit.

figure 9-3 editing the process guidance document using infopath

Figure 9-3 Editing the Process Guidance document using InfoPath

Back up the process guidance document, make your changes using InfoPath, and then open ProcessGuidance.htm to view your changes in the Web browser.

Customizing Work Item Types

Depending upon the methodology template you choose, your team project will be able to use various work item types. For example, MSF for Agile Software Development defines Scenarios, Quality of Service (QoS) Requirements, Bugs, and Tasks. The schema or available fields are also predefined by Microsoft. This is also an area that can be customized, especially for shops that want to create new work item types or alter existing work items to ask additional questions. For example, a company might want to customize the schema of a task, to prompt for the Security Classification of the task. In addition, it might not want the users to enter free-form text, but instead keep them constrained to a predefined list of Unclassified, Confidential, and Secret. By using some export and import tools provided by Microsoft, customization can be easily accomplished.

The Team System Partner Extensibility Kit provides four command-line utilities:

  • witexport.exe.

    Exports an existing work item type from a team project as XML.

  • witimport.exe.

    Imports an XML work item type definition to a team project or validates a definition before import.

  • glexport.exe.

    Exports global lists defined on the Team Foundation Server as XML.

  • glimport.exe.

    Imports global lists defined in XML to a Team Foundation Server.

Here are the steps to export an existing work item type, add a new field, and then import the type back into Team Foundation Server:

  1. Open a command prompt and type the following command to export the standard task work item type to another file:

    witexport /f SampleTask.xml /t TFSSer_ver /p TeamProjectName /n "Task"

  2. Open a command prompt and type the following command to export any global lists currently in Team Foundation Server:

    glexport /f GlobalLists.xml /t TFSServer

  3. Open the GlobalLists.xml file and add the following list to the <GLOBALLISTS> element:

      <GLOBALLIST name="SecurityClassifications">     <LISTITEM value="Unclassified"/>     <LISTITEM value="Confidential"/>     <LISTITEM value="Secret"/>     <LISTITEM value="Top Secret"/>   </GLOBALLIST>

  4. Open the SampleTask.xml file and add the following field to the other fields in the file:

    <FIELD name="Security" refname="Sample.Security" type="String">   <HELPTEXT>The security classification of this task</HELPTEXT>   <ALLOWEDVALUES expanditems="true" filteritems="excludegroups">     <GLOBALLIST name="SecurityClassifications"/>   </ALLOWEDVALUES></FIELD>

  5. Specify where you want the new Security field to be displayed on the UI by adding the following after the Iteration control down in the FORM section of SampleTask.xml:

    <Control Type="FieldControl" FieldName="Sample.Security" Label="Security Classification" LabelPosition="Left" />

  6. Open a command prompt and type the following to import the new global list:

    glimport /f GlobalLists.xml /t TFSServer

  7. Open a command prompt and type the following to import the updated task work item type:

    witimport /f SampleTask.xml /t TFSServer /p TeamProjectName

  8. Launch Visual Studio. Open Microsoft Visual Studio 2005 Team Explorer and create a new task work item for your team project. You should see a new field with a drop-down list containing the valid choices, as shown in Figure 9-4.

figure 9-4 updated task work item containing the new security classification field

Figure 9-4 Updated task work item containing the new Security Classification field

When defining new fields, there are several properties you can associate with the field. In the preceding example, I associated only some help text (ToolTip) and a constrained list of valid answers. There are more properties and constraints you can associate with a field, for example:

  • <REQUIRED/>.

    The field is required to be nonempty.

  • <READONLY/>.

    The field cannot be modified.

  • <EMPTY/>.

    The field value will be cleared on commit, and the user cannot enter any value. Used primarily during state transitions.

  • <FROZEN/>.

    After a field has a value after a commit, it can no longer be modified. It can, however, be cleared using an <EMPTY/> constraint and filled in again later. Used primarily during state transitions.

  • <CANNOTLOSEVALUE/>

    After a field has a value, it cannot be cleared or made empty.

  • <NOTSAMEAS field=“Example”/>.

    The field value cannot have the same value as the value in the field “Example”. For example, two fields cannot be empty at the same time, or the “Code Reviewer” field value cannot be the same as the “Assigned To” field value. Should be used for fields of like type. It is not supported for PlainText or HTML fields.

  • <VALIDUSER/>.

    The field value must be a valid user who is a member of Team Foundation Server Everyone. Note: If the <REQUIRED/> rule is not specified, this field will accept an empty value. Used for String field types.

  • <VALIDDATE mustbe=“after now”/>.

    Validates a date field. The mustbe value can be either “after now” or “not after now”. “after now” is after the current time; “not after now” requires the field value to be the current time or before. Used for DateTime field types.

  • <ALLOWEXISTINGVALUE/>.

    Allows a field to retain an existing value, even if that value is no longer allowed. The alternative and default behavior is to force the user at edit time to conform to the latest allowed values for that field. This element has a modifying effect only on the elements in the same block. It cannot accept “for” or “not” attributes.

  • <MATCH pattern=“<pattern>”/>.

    Enforces basic pattern matching for strings only. “<pattern>” should be replaced with the string pattern you want to match. Valid values are “A”, “N”, and “X”. All other values are taken as literals. “A” represents an alphabetical character; “N” represents a numeric character; “X” represents any alphanumeric character. Supported only for String field types. You can specify multiple <MATCH> elements. If just one element succeeds, the field has a legal value.

  • <ALLOWEDVALUES>.

    An enumerated list of values that is presented to the user as a drop-down list. Users must pick one of the values on this list. I used it in my example.

  • <SUGGESTEDVALUES>.

    An enumerated list of values that is presented to the user as a drop-down list. Users can select any one of the values or enter their own value, which is not one of the suggestions.

  • <PROHIBITEDVALUES>.

    Users cannot save a work item if the field contains any prohibited values. Prohibited values are typically used when a value was previously allowed but is no longer valid.

  • <DEFAULT>.

    When a user creates a new work item or edits a work item, the <DEFAULT> element fills in a field value if that field is empty. If a field already has a value, the default rule is ignored.

  • <COPY>.

    When a user creates a new work item or edits a work item, the <COPY> element fills in a field value regardless of any exiting value already in the field.

  • <SERVERDEFAULT>.

    Unlike <DEFAULT> and <COPY>, which fill in values at the beginning of editing, the <SERVERDEFAULT> rule fills in a value when the work item is committed to the database. This happens at Save time and the user cannot override the value. Fields appear read-only on the form. This rule is used for fields such as “Last Changed By” and “Last Changed On” to support secure audit trails.

You can set many other characteristics of work items. One of the more interesting is workflow—you can define the valid states, legal transitions, and legal reasons for those transitions. A common example is to consider the status field of a work item. Once a status is given, the transitions to another status, along with associated reasons, must be considered. For example, take a work item type with three status states: Active, Unapproved, and Closed. The Unapproved state precedes the Active state, and that Active state precedes the Closed state. Reasons identify why the user is changing from one state to another.

Customizing Version Control

Project managers or team leads can configure a team project's version control to include one or more check-in policies, such as clean build, associate with work item, or running one or more tests on the code. Additional policies can be created and registered (as I will discuss later in this chapter).

One way to customize version control is to add additional file types that can be handled by Team System. By default, only certain file types are supported. Some image files, such as .bmp and .tif files, for example, are not supported by default. By right-clicking the Team Foundation Server in the Team Explorer window, you can configure the file types that are supported, even specifying which ones support multiple check-outs. (See Figure 9-5.)

figure 9-5 configuring version control to handle additional file types such as images

Figure 9-5 Configuring version control to handle additional file types such as images

Customizing Reporting

Remember that the reports found in Team System are simply Microsoft SQL Server™ 2005 Reporting Services reports. These are Report Definition Language (.rdl) files that have been created by Microsoft and uploaded to Reporting Services and made available through the project portal. There are a number of ways to customize these reports:

  • Create new reports.

    By using SQL Server Business Intelligence Developer Studio®, you can create new reports.

  • Edit existing reports.

    By editing the .rdl files provided by Microsoft, you can customize the existing reports with your company heading, formats, or additional fields.

  • Use Report Builder.

    By creating one or more report models, you can further empower your team to build its own custom Team System reports on their own.

TIP
Remember, once you create some new reports, you can make them part of any future team projects by exporting the respective methodology template, adding the .rdl files to the appropriate folder, and then importing the template.

Customizing Project Portal

Portals are great. They are a quick way to build a clean Web site, with much of the basic framework (security, menus, lists, configuration, and themes) already built in. Team System uses the project portal as the one place to go for all documents, reports, and lists. Any member of the core team, as well as extended members who may not have Visual Studio, Microsoft Office Excel®, or Microsoft Office Project, can visit the portal for periodic status reports.

In the Beta edition of Team System, the project portal is hosted on WSS 2.0, running on Microsoft Windows Server™ 2003. This platform offers many customization options. Anybody with a few days' training in WSS can easily alter the look and feel of the portal in many ways:

  • Add new documents

  • Add new lists of documents

  • Add new users or change existing users' capabilities

  • Alter the WSS site template, changing the look and feel

Extending Team System

This section focuses on the more complex tasks of altering Team System in creative ways to offer new functionality that didn't exist before. This will be of interest to internal IT teams, who want to tweak Team System, as well as independent software vendors (ISVs) who may want to create and sell add-ons and plug-ins to Team System. Whatever your motivation, Microsoft has the support for you.

Each tool offered in Team Foundation Server is highly extensible and can be automated. Work item tracking, version control policies, build scripts, and programmability interfaces all enable customers to tailor Team System and Team Foundation Server to their specific needs. In addition, at the core of Team Foundation Server is a set of mechanisms intended to enable partner- and customer-written tools to integrate into the Team Foundation Server environment as first-class citizens.

Team System can be extended on any of its three tiers:

  • Database Tier.

    SQL Server 2005 offers many extensibility and integration options.

  • Application Tier.

    ASMX Web services and a robust Microsoft .NET object model offer many options.

  • Client.

    Visual Studio Integration Partners (VSIP) have long been successful at adding new functionality to the client; many APIs support it.

There are object models and extensibility options for each of these tiers, as seen in Figure 9-6. There is plenty of support outside of Team System for modifying SQL Server 2005 and Microsoft ASP.NET Web services, for example, so the possibilities are limitless.

figure 9-6 extensibility architecture found in team foundation services

Figure 9-6 Extensibility architecture found in Team Foundation Services

We'll look at a more distinct set of ways that Team System can be extended:

  • Core Services.

    Build new tools to support new artifacts/types, extend the databases, add new Web services, or link to other tools' artifacts, raise and subscribe to events, integrate with Team Explorer, or add pages to Project Creation Wizard.

  • Work Item Tracking.

    Respond to events, spawn work items, link to other work items, integrate with other client applications, or build new client applications (that is, Web applications).

  • Version Control.

    Respond to events, add (diff/merge) support for new file types, participate in integrated check-in, or define new policies.

  • Reporting.

    Extend the database or data warehouse with other domain- or tool-specific data; perform data mining.

  • Team Build.

    Add new build tasks; track other build systems' data in the Team Foundation Server database.

  • Project Portal.

    Add new Web parts, such as queries or Reporting Services reports.

Extending the Core Services

Not only do the work item, version control, and build services have full integration interfaces, but Microsoft has created an extensive, pluggable array of services by which you can extend Team System.

Team Foundation Server's shared services are detailed in the following sections.

Linking Service

The linking service enables tools to establish loosely coupled relationships (“links”) between data elements they hold. For example, in Team Foundation Server, the relationship between a defect (bug) work item and the source code that was changed to fix the defect is held as this sort of link. To participate, a tool must implement methods that expose their data as Team Foundation Server “artifacts,” and it must respond to queries against them. Using this facility, a tool can participate in a relationship that it wasn't initially designed to recognize.

Security Service

The security service implements groups of Microsoft Windows identities within Team Foundation Server. These groups, local to a Team Foundation Server, are used to assign permissions to Team Foundation Server artifacts and services. The groups can be administered without the help of the IT department. When a new tool is introduced to Team Foundation Server, it should respect these groups by using the group security service API. The security service also provides authorization services. Tools that do not offer their own authorization mechanism have the option to use the security service to secure objects and establish permissions.

Eventing Service

The eventing service is a Web service–based publication and subscription mechanism. As you'd expect, tools can raise events to the eventing service. Subscribers can register to receive notification when an event matches their subscription criteria. A notification recipient can either be a Web service or an e-mail address. When it's a Web service, the subscription includes the URL of a Web service to be called when a notification is to be delivered. When it's an e-mail address, a notification can be delivered through e-mail via an SMTP server.

Visual Studio Team System includes a flexible, extensible mechanism for subscription and notification. The most common user notification mechanism is e-mail, although other mechanisms will be supported in future versions. The most common service notification mechanism is Web services. The Team Foundation Notification Service is a reliable, asynchronous publish/subscribe event notification system supporting the distributed Visual Studio Team System environment. Users and other services can subscribe to those events. When the source tool raises an event, the event is matched against subscriptions, and notifications are generated. For example, Figure 9-7 shows the notification alerts implemented directly inside the Visual Studio 2005 integrated development environment (IDE).

figure 9-7 configuring visual studio 2005 to send alerts when certain events occur

Figure 9-7 Configuring Visual Studio 2005 to send alerts when certain events occur

Classification Service

The classification service works in coordination with the linking service to allow classification of Team Foundation Server artifacts according to predefined taxonomies. This enables tools whose artifacts do not share a common “natural” taxonomy to organize their data in such a way that cross-tool reporting along common axes is possible. For instance, if work items are naturally organized by team and tests are naturally organized by component, tests can additionally be organized by team to enable them to be reported alongside work items.

Registration Service

When a new tool is introduced to Team Foundation Server, its artifact types, link types, event schemas, and service interfaces are registered via the registration service. Clients of the new tool discover its location by asking the registration service. Client configuration is easier because the client only needs to know how to find the registration service. This also makes it easier to move services from one Host to another because the registration service will redirect clients as needed.

Extending Work Item Tracking

Team Foundation Server includes a robust API from which you can build many custom applications that manipulate work items. Although this can be done directly with the ASMX Web Services, it is best to use the provided .NET object model because it simplifies the complexities of the Web Service API. By referencing the Team Foundation Client and Work Item Tracking assemblies, you can connect to a Team Foundation Server and manipulate its work items.

This extensibility creates many opportunities, from building your own client tools (Web-based, for example) to building your own Web services, tied into the eventing system previously mentioned, to spawn work items. Consider a scenario in which you want to “hook” into Team Foundation Server, and whenever a new scenario or bug work item is created, you want to “spawn” several related task work items. This would almost be like a macro, in which a few keystrokes spawned many more. Productivity like this is important because using Team Explorer to add work items can be tedious. Any automation that you can provide to your team can really speed up your process.

Here's some sample code for automating the creation of work items:

using System; using Microsoft.VisualStudio.TeamFoundation.Client; using Microsoft.VisualStudio.Currituck.Client; namespace AdventureWorks {   class Program   {     private static void AddWorkItem(string AssignedBy,string Pwd,       string type,string title, string state, string assignedTo,       DateTime createdDate, string disciplineOrType,       string areaPath, string iterationPath)     {       // Connect to TFS       TeamFoundationServer tfs = new TeamFoundationServer("TFS1",         new System.Net.NetworkCredential(AssignedBy, Pwd, "AW"));              // Access the Work Item Store       WorkItemStore store =         (WorkItemStore)tfs.GetService(typeof(WorkItemStore));       // Add Work Item       WorkItemType taskType =         store.Projects["AdventureWorks"].WorkItemTypes[type];       WorkItem item = new WorkItem(store, taskType);       item.Title = title;       item.State = state;       item.Fields["Assigned To"].Value = assignedTo;       item.Fields["Created Date"].Value = createdDate.ToShortDateString();       item.Fields["Discipline"].Value = disciplineOrType;       item.Fields["Area Path"].Value = areaPath;       item.Fields["Iteration Path"].Value = iterationPath;       // Save       item.Save();     }     static void Main(string[] args)     {       AddWorkItem("PM", "P@ssw0rd", "Task", "Design a Blog App",         "Active", "Architect", DateTime.Today, "Development",         @"\Development", @"\Alpha");     }   } }

NOTE
The preceding code uses the Extensibility Toolkit. After installing the toolkit, you need to reference two assemblies: Microsoft.VisualStudio.Currituck.Client.dll and Microsoft.VisualStudio.TeamFoundation.Client.dll. Both are installed into the C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies folder.

Extending Version Control

Team System's version control can be fully automated using APIs, much like the previous work item section. By referencing the appropriate .NET assemblies, you can automate the check-in, check-out, and other administrative functions. With this kind of capability, you can build your own add-ins or plug-ins for other environments, much like what SourceGear has done with its Allerton product (which you will read about later in this chapter).

Here's some sample code that automates version control:

using System; using System.IO; using Microsoft.VisualStudio.Hatteras.Client; using Microsoft.VisualStudio.TeamFoundation.Client; namespace AdventureWorks {   class Program   {     static void Main(string[] args)     {       // Connect to TFS using the TeamFoundationServerFactory       TeamFoundationServer tfs =          TeamFoundationServerFactory.GetServer("TFFS1");       // Reference the Version Control service       VersionControl versionControl =          (SourceControl)tfs.GetService(typeof(VersionControl));       // Create a workspace       Workspace workspace = versionControl.CreateWorkspace("VCExample",         sourceControl.AuthenticatedUser);       // Create a mapping to associate a path on the server with local disk       workspace.CreateMapping("$/", @"c:\VCExample");       // Get the files from the repository       workspace.Get();       // Create a directory and a test file       String topDir = Path.Combine(workspace.Folders[0].LocalItem, "sub");       Directory.CreateDirectory(topDir);       String fileName = Path.Combine(topDir, "basic.cs");       using (StreamWriter sw = new StreamWriter(fileName))       {         sw.WriteLine("revision 1 of basic.cs");       }       // Add the directory and file to version control       workspace.PendAdd(topDir, true);       // Display pending changes       PendingChange[] pendingChanges = workspace.GetPendingChanges();       Console.WriteLine("Your current pending changes:");       foreach (PendingChange pendingChange in pendingChanges)       {         Console.WriteLine("  path: " + pendingChange.LocalItem +           ", change: " +            PendingChange.ChangeTypeToString(pendingChange.ChangeType));       }       // Checkin the items we added (will create a new changeset)       int changesetNumber =          workspace.CheckIn(pendingChanges, "Sample changes");       Console.WriteLine("Checked in changeset " +          changesetNumber.ToString());       // Checkout and modify the file       workspace.PendEdit(fileName);       using (StreamWriter sw = new StreamWriter(fileName))       {         sw.WriteLine("revision 2 of basic.cs");       }       // Get the pending change and check in the new revision       pendingChanges = workspace.GetPendingChanges();       changesetNumber = workspace.CheckIn(pendingChanges, "Modified basic.cs");       Console.WriteLine("Checked in changeset " + changesetNumber.ToString());     }   } }

Another interesting way to extend Team System's version control is by creating your own custom check-in policies. Remember that Team System includes only a few policies out of the box. Your team or company might want to create and deploy something more interesting. For example, ensure that your domain-specific business rules are not violated, such as Sarbanes-Oxley (SOX) Requirements.

A custom check-in policy needs to implement two interfaces: IPolicyDefinition and IPolicyEvaluation. The IPolicyDefinition interface assists the user in identifying and enabling the policy, and the IPolicyEvaluation interface performs the actual policy validation and messaging during a check-in.

Here's some sample code that implements a simple check-in policy:

using System; using System.Windows.Forms; using Microsoft.VisualStudio.Hatteras.Client; namespace AdventureWorks {   [Serializable]   public class SimplePolicy : IPolicyDefinition, IPolicyEvaluation   {     [NonSerialized]     public static readonly PolicyFailure[] m_noFailures =       new PolicyFailure[0];     private IPendingCheckin m_pendingCheckin = null;     // IPolicyDefinition Members     // Description displayed in the UI.     public string Description     {       get { return "Prompt user to decide if they are in compliance."; }     }     // Method invoked by policy framework when checkin policy created     public bool Edit(System.Windows.Forms.IWin32Window parent,        IServiceProvider serviceProvider)     {       if (MessageBox.Show(parent,         "Do you want to turn on the Prompt Policy?", "Prompt Policy",         MessageBoxButtons.YesNo) == DialogResult.Yes)       {         return true;       }       return false;     }     // Instructions stored with the definition on the VC server     public string InstallationInstructions     {       get { return "To install this policy, follow the instructions!"; }     }     // Policy type, displayed in a list of all installed policy types     public string Type     {       get { return "Prompt Policy"; }     }     // Policy type description, displayed when the policy type is selected     public string TypeDescription     {       get { return "This policy prompts the user checkin or not."; }     }     // IPolicyEvaluation Members     // Method to perform the actual evaluation,  called by the policy framework     public PolicyFailure[] Evaluate()     {       if (MessageBox.Show("Should we let you checkin?",         "Evaluate", MessageBoxButtons.YesNo) == DialogResult.Yes)         return m_noFailures;       else       {         PolicyFailure[] toReturn = new PolicyFailure[1];         toReturn[0] = new PolicyFailure(           "You told us not to let you checkin.", this);         return toReturn;       }     }     // Method instantiating policy (accesses the pendingCheckin object)     public void Initialize(IPendingCheckin pendingCheckin)     {       m_pendingCheckin = pendingCheckin;       m_pendingCheckin.PendingChanges.CheckedPendingChangesChanged +=         new EventHandler(PendingChanges_CheckedPendingChangesChanged);     }     // Method to dispose the policy object     public void Dispose()     {       m_pendingCheckin.PendingChanges.CheckedPendingChangesChanged -=         new EventHandler(PendingChanges_CheckedPendingChangesChanged);       m_pendingCheckin = null;     }     // Event handler for changes in the checked-in source files     private void PendingChanges_CheckedPendingChangesChanged(       Object sender, EventArgs e)     {       OnPolicyStateChanged(Evaluate());     }     // Event subscribed-to by the policy framework     public event PolicyStateChangedHandler PolicyStateChanged;     // Method to notify the policy framework that policy compliance has changed     private void OnPolicyStateChanged(PolicyFailure[] failures)     {       PolicyStateChangedHandler temp = PolicyStateChanged;       if (temp != null)       {         temp(this, new PolicyStateChangedEventArgs(failures, this));       }     }     // Method called if the user double-clicks on a policy failure in the UI     public void Activate(PolicyFailure failure)     {       MessageBox.Show("The next time you are prompted, try clicking \"Yes.\"",         "How to fix your policy failure");     }     // Method called when user presses F1 with an active policy failure     public void DisplayHelp(PolicyFailure failure)     {       MessageBox.Show("This policy lets you decide if you are in compliance.",         "Prompt Policy Help");     }   } }

Extending Reporting

Initially, as you begin adopting Team System, your team probably won't begin using 100 percent of its capabilities. The odds are that you already have (and will continue to use, at least for awhile) some other work item, bug-tracking, version control, or build systems. These might be popular third-party products or home-grown solutions. Either way, you are or will be storing a lot of other data outside of Team System.

One way to extend reporting is by combining the data from your other systems with data inside of Team System. For example, if you are using a third-party build utility, you might want to report on that data to the Team System users.

Remember that Team System includes a data warehouse in which data from work item tracking, version control, builds, and testing tools are stored. This data warehouse includes both relational and online analytical processing (OLAP) databases. The OLAP data warehouse consists of several relational star schema databases that are implemented as a number of SQL Server 2005 analysis services cubes. At the center of the star schemas are several types of facts. Each type of fact has a primary relational table and a cube in the OLAP database that draws from that table. Each fact is composed of dimensions, measures, and details.

Cubes are the main objects in OLAP, a technology that provides fast access to data in a data warehouse. A cube is a set of data that is usually constructed from a subset of a data warehouse and is organized and summarized into a multidimensional structure defined by a set of dimensions and measures.

Dimensions are properties that are used to slice the data in a report. For example, the Work Item facts include Type and State dimensions. Dimensions are realized in the relational database as tables, with foreign key references to the dimension tables from the primary fact table.

Measures are properties that are aggregated (counted, added, and so forth) to provide the quantitative values in reports. For example, the version control's CodeChurn cube includes LinesAdded, LinesRemoved, and LinesChanged measures. Measures are columns in the primary fact table.

Details are columns that appear in the relational database only. They are generally longer text strings such as work item titles that are used primarily in list reports that can be drawn as efficiently from a relational database as it can from an OLAP database. Details are columns in the primary fact table that do not appear in the OLAP cube.

Understanding the data warehouse is important because Team System also includes a service that manages the updates to the warehouse. It allows custom or third-party tools to participate in the warehouse by describing their schema extensions and by providing an adapter to pull data from its operational store and place it in the warehouse. The schema is described in XML. The adapter is a managed assembly that implements an IWarehouseAdapter interface and uses the warehouse object model to interact with the warehouse.

If you will build your own adapter, you need to also implement the IWarehouseAdapter interface, and specifically the following methods:

  • void Initialize(IDataStore ds).

    Initializes your adapter.

  • InitRunResult InitRun().

    Provides the means by which an adapter can indicate that it will change schema on this run.

  • void Run( ).

    Performs the primary work by pulling data from the data store and writing it to the warehouse.

  • void RequestStop( ).

    Stops your adapter in an orderly fashion if the service is taken down.

Extending Team Build

Team Build includes many common tasks to support actions such as running tests and getting sources from version control. Your build process, however, might require other tasks to be run as part of the process. For example, a build administrator might want to have output assemblies deployed to a specified location after the compilation is complete but before testing begins, or a company might require a specific build numbering system, thereby overriding one of the default numbering schemes included in Team Build.

Team Build uses MSBuild for building applications and supports custom tasks to extend the build process. This topic discusses concepts for creating a custom Team Build task. Team Build can be extended so that a custom task can be executed at any phase of the build process. These tasks are simply .NET classes that inherit from Task. This class is found in the Microsoft.Build.Utilities namespace. The class derived from the Task class must implement the Execute method, which is invoked by MSBuild.

The first step is to code your custom task (a custom BuildNumberGenerator in this example). This task generates a unique build number based on current time in milliseconds. Take note of the Output attribute, which identifies the BuildNumber property as being an output of the Task.

using System; using Microsoft.Build.Utilities; using Microsoft.Build.Framework; namespace AdventureWorks {   public class BuildNumberGenerator : Task   {     private string buildNumber;     public override bool Execute()     {                   buildNumber = DateTime.UtcNow.Ticks.ToString();       return true;     }     [Output]     public string BuildNumber     {       get { return buildNumber; }     }   } }

After coding, you need to define the build type of this custom task by using the Team Build client. The build type consists of TeamBuild.proj, VCOverrides.props, and WorkspaceMapping.xml files. Every build type is represented by a folder that contains these files. After creating the build type, you need to customize the definition by referencing your custom task. For this example, you need to check out the TeamBuild.proj file and add the following code to the file:

<!-- Add UsingTask line just after import statement - - > <UsingTask    TaskName="BuildNumberGenerator.BuildNumberGenerator"    AssemblyFile="BuildNumberGenerator.dll"/> <! -- Override the Target near the end of proj file - - > <Target Name = "BuildNumberOverrideTarget" >   <BuildNumberGenerator>      <Output TaskParameter="BuildNumber" PropertyName="BuildNumber"/>    </BuildNumberGenerator>  </BuildNumberOverrideTarget>

After coding and configuring the task, you need to add your task assembly to the same location as TeamBuild.proj by using the appropriate command-line utility.

Extending Project Portal

The project portal can be extended by adding new Web parts or by building custom ones. These new Web parts can expose specific reports, custom queries, or other functionality. For example, SQL Server 2005 Reporting Services allows any reports to be called directly via a URL. By following these steps, you can add a Page Viewer control to your portal site and point it toward a report:

  1. Modify the project portal and choose Design this Page.

  2. Add a Page Viewer Web part (you may have to search or import).

  3. Specify the link (URL) to the report. For example: http://server/reports/pages/report.aspx?ItemPath=%2fAW%2fWork+Item+List_

  4. Specify any appearance and layout settings.

What you end up with is a Web part that executes the report when the portal is refreshed. (See Figure 9-8.) This way, you can have your important reports executed and the results available right on the main page, without requiring a user to click anything.

Creating your own custom Web parts is the true definition of project portal extensibility. Rather than just use one of the built-in Web parts, such as the Page Viewer, the WSS architecture allows developers to build their own Web parts, deploy them to WSS, and install them so they can be used on various pages.

figure 9-8 adding a page viewer web part to the project portal

Figure 9-8 Adding a Page Viewer Web part to the project portal

The Microsoft Windows SharePoint Products and Technologies 2003 SDK contains conceptual overviews, programming tasks, samples, and references to guide you in developing solutions based on SharePoint products and technologies.

From Visual Studio, you can create a new Web Part Library project in your favorite language. This project needs to reference the WSS assembly and should specify a good version number and a strong name.

Here's some sample code that implements a simple Web part:

using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Web.UI; using System.Web.UI.WebControls; using System.Xml.Serialization; using Microsoft.SharePoint; using Microsoft.SharePoint.WebPartPages; using Microsoft.SharePoint.Utilities; using System.Web.UI.HtmlControls; namespace MyWebParts {   [XmlRoot(Namespace="MyWebParts")]   public class SimpleWebPart : WebPart   {     private const string defaultText = "Team System";     private string text=defaultText;     HtmlButton _mybutton;     HtmlInputText _mytextbox;     // Event handler for button control to set Title property     public void _mybutton_click (object sender, EventArgs e)     {       this.Title = _mytextbox.Value;       try       {         this.SaveProperties=true;       }       catch       {         Caption = "Error... Could not save property.";       }     }     // Override to create the objects for the Web Part's controls     protected override void CreateChildControls ()     {       // Create _mytextbox control.      _mytextbox = new HtmlInputText();      _mytextbox.Value="";       Controls.Add(_mytextbox);       // Create _mybutton control and wire its event handler.      _mybutton = new HtmlButton();      _mybutton.InnerText = "Set Web Part Title";      _mybutton.ServerClick += new EventHandler (_mybutton_click);       Controls.Add (_mybutton);     }     [Browsable(true),Category("Miscellaneous"),       DefaultValue(defaultText),WebPartStorage(Storage.Personal),       FriendlyName("Text"),Description("Text Property")]     public string Text     {       get { return text; }       set { text = value; }     }     protected override void RenderWebPart(HtmlTextWriter output)     {       RenderChildren(output);       output.Write("<BR>Text Property: " + SPEncode.HtmlEncode(Text));     }   } }

You can take this basic structure and scale it out to almost any functionality. Web parts are essentially ASP.NET server controls that render the appropriate HTML back to the portal when asked to do so. You could add code to create work items or manage version control and start building a Team System Web client (something that's missing from the current offering from Microsoft).

NOTE
To develop custom Web parts, you need to download the SharePoint Services SDK from http://www.microsoft.com.

Visual Studio 2005 Tool Integration

In addition to exploiting these shared services, you can also take advantage of a variety of additional plug-ins to fully integrate a tool into Team System. Figure 9-9 shows the various places where you can plug in your tools, services, and data.

figure 9-9 using plug-ins within team system

Figure 9-9 Using plug-ins within Team System

If you're planning on integrating tools with Team System, you should use the Visual Studio Integration Partner program SDK. Using the SDK will result in a consistent client experience, integrating your UI into the Visual Studio 2005 IDE. Alternatively, you can build a standalone .NET application that accesses the application tier by using the intelligent proxy layer.

Here are some specific areas of integration that are possible with Team System:

  • Add creation of your tool's artifacts to the Team Project Creation Wizard (and, by implication, the process template that drives it).

  • Make your tool and its data visible as nodes on Visual Studio 2005 Team Explorer.

  • Use the warehouse dynamic schema modification facilities to extend the warehouse with your tool's data, and then build a warehouse adapter to pull your tool's operational data into the warehouse structures.



Working with Microsoft Visual Studio 2005 Team System
Working with Microsoft Visual Studio 2005 Team System (Pro-Developer)
ISBN: 0735621853
EAN: 2147483647
Year: 2006
Pages: 97

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net