Team Foundation Server offers many services out of box. Source Control, Build Automation and Work Item Tracking are the three foundation services that generate data. Any action that happens related to these services either creates a new record in the database of TFS or updates an existing record. Services of Reporting and Team Portal consume that generated data to give us excellent reports and provides visibility to those reports along with other collaborative features of SharePoint. All these services are tied together with the Integration Service. Integrated set of services is the unique offering of TFS which had made it one of the top Application Lifecycle Management provider world over.
These out of box features support almost any requirement related to the Application Lifecycle Managements (ALM) of any organization. In such a case why do we need to extend the services of TFS? The need arises from the expectation of organizations to implement their own processes through TFS rather than adhering to the process that is provided out of the box. It also arises from a larger requirement of every organization to automate process that will then become more productive and will also result in higher quality of the software that they are building.
Let me explain these with some examples.
Example 1: Organization ‘A’ wants that as soon as a team project is created, there should be a certain structure of iterations and areas created, certain work items with fixed title should be added and those should be assigned in specific iterations and areas, that are already created. Off course somebody can do this task manually. For example Team Lead can be given a task that fulfills that organizational requirement of process. But doing it manually is to open a chance of omissions and commissions. The team lead may not be available to do it after the project is created and before the structure is required. Team lead also may commit an error while doing that task leading to improper implementation of process.
Example 2: Organization ‘B’ is interested in using TFS for a Java project. They also want that every check-in should be preceded with a quality check that involves a third party tool say for example CheckStyle. If that check is successful, then only the code should be checked in. To keep it as voluntary, could mean adeveloper may or may not do it and more over there will not be any data generated about results of that quality check. It then becomes necessary to have a custom check-in policy that extends the normal functionality of TFS and works with an IDE like Eclipse.
Example 3: Organization ‘C’ wants to run a homemade tool that enters the result of build in their own project management software. They also want that the built assemblies should be packaged and deployed on a staging server and that should happen automatically reducing any chances of error in those activities.
There are many such examples where organizations are not satisfied with features and functionality provided out of box by TFS. They need some functionality built on top of standard features of TFS to make it more user friendly, automated and to target a larger scope than what is available.
Fortunately for us, Microsoft has published APIs of TFS for the purpose of extending the functionality of TFS by anyone who is a legal user of TFS. These APIs are in the form of built components (Assemblies that are packaged as.dll files) that are copied on our machines when we install Visual Studio or even the Team Explorer. Some additional assemblies are copied on the machine where the TFS Application Tier is installed. These assemblies provide us some classes and interfaces that we can use in our applications. I am providing a sample list of these assemblies here. It is not an exhaustive list but some of the most commonly used classes and interfaces and where to use those.
Now the important question is how do we use these classes and interfaces? What kind of applications can we create?
Let us start discussion on those questions with the help of case of Organization ‘A’. They want to achieve something automatically when TFS completes the action of creation of a project. This is a typical event – event handler paradigm. TFS publishes number of events and we can write event handlers for that. These event handlers are of two different types. The traditional event handlers of TFS 2010 circa are web services that run anywhere that is accessible to TFS. We need to create a subscription in TFS for an event so that our web service will get notified when the event happens. Some time back, I had written an article about creating such a web service and subscription which you can still use Team Foundation Server 2010 – Eventing Service - Subscribing to events. A similar concept of subscription also works for WCF services. Ewald Hofman had written a tutorial for that before he joined Microsoft, when he was an MVP. You can access it at http://www.ewaldhofman.nl/post/2010/08/02/how-to-use-wcf-to-subscribe-to-the-tfs-2010-event-service-rolling-up-hours.aspx
Since TFS 2010, Microsoft introduced a much more powerful concept of in-process event handlers. These type of event handlers that I had mentioned earlier, run out of process and so have limited access to objects on TFS. The new event handlers can access almost everything on TFS since they run in the process of TFS service itself. This has now become de-facto standard for creating event handlers on TFS. One can learn how to create such subscriber from a tutorial published by Martin Hinshelwood at http://nakedalm.com/team-foundation-server-2010-event-handling-with-subscribers/. As Martin has mentioned in the tutorial, we are extending TFS by implementing the interface ISubscriber.
As our case of the organization A suggested, we create an event handler. The first choice is to create the in-process event handler. But here my experience is that in-process event handler for Project Created Event is not such a reliable mechanism. So I have to fall back on the out-of-process mechanism. Another issue that I have observed is that when a new iteration is added to the structure of iterations that is not available to be assigned to a new work item. This is because data stores of ‘Common Structure Service’ and ‘Work Item Tracking Service’ are different. For TFS it takes some time to synchronize those. TFS does that synchronization by queuing a job on the ‘TfsJobAgent’ service.
This ‘TfsJobAgent’ service opens another opportunity for us to explore the extensions. This is a service that runs various standard and custom jobs in a queue. Once we put a job in the queue, we can ‘fire and forget’ it. It will be run by the service when its turn comes in the queue. But then it is asynchronous. We cannot determine when the job finishes in the program that is putting the job in the queue which in this case happens to be our custom event handler.
So we have no option than to fall back on the old, tried and trusted technology of writing a web service and subscribing for ‘ProjectCreatedEvent’ to notify this web service. But we achieve the result in that way.
Now let us take the case of Organization ‘B’. The task of making a check to decide whether to allow check-in to succeed or to fail is that of Check-in policy. It is a watchdog that reminds me of Kerberos which is the name of the three headed dog outside the cave of Medusa. Btw if you have seen something similar in one of the movies of Harry Potter, then no – that’s not the original idea. Greeks have the right to be called original there, after all they were the first to visualize it. So, we have a number of check-in policies bundled with TFS but none of them is to call a third party software to do the check. So we create a custom check-in policy. How to create such a custom check-in policy and deploy it can be found in one of my old articles VSTS - How to create and deploy custom check-in policy. Although that was published way back in 2008, it holds good even today with TFS 2013.
But another issue that we face in this case is we want that check-in policy to work on a Java project in the IDE like Eclipse. And unfortunately our custom check-in policy written using .NET does not work in that environment. Hostile! So does that mean that we hit a wall when it comes to writing client side custom code that can use TFS? Not to worry. Microsoft has published and updated a SDK in Java for doing just that type of programming. You can download it from http://www.microsoft.com/en-us/download/details.aspx?id=22616. That MSDN page mentions that it is for TFS 2012 but have no fear, Martin Woodward who is one of the forces to reckon with about this SDK has confirmed that it works with TFS 2013 as well!
Now the question is how do we program it and deploy it in the Java – Eclipse environment? I had written exactly that in this set of articles - Developing a Custom Check-in Policy using TFS 11 SDK for Java and Run and Deploy Custom Check-in policy using TFS SDK 11 for Java. We can see that TFS is truly technology agnostic. Not only for use, but also for developing extensions too.
Now we reach the not so peculiar case of Organization ‘C’. In fact many organizations want to customize the build process so that it behaves the way they want it to. TFS Build is most versatile about customization and extension. We can do it in four different stages.
Stage 1: We take the build definition template as it is provided by Microsoft. It is actually a XAML workflow. We can open it in workflow designer in Visual Studio. When we give reference to TFS Build API class libraries, we get many TFS related activities in the toolbox of that designer. Then we add one or multiple activities from toolbox on the designer surface at the appropriate places in the standard build workflow. We can upload that to TFS with a different name. Details of this process are provided by VS ALM MVP Gouri Sohoni in this article - Build Customization using Visual Studio 2010. Although she had written it for TFS 2010, I assure you that it works the same in TFS 2012 and TFS 2013 too.
Stage 2: We want to do build template customization the way it is mentioned for Stage 1 but do not find the appropriate activity in toolbox. After some contemplation we realize that if we combine multiple such activities, we can achieve the customization that we want. So we create a custom XAML activity that fulfills our need and then put it in the toolbox. Now we can drag and drop it on the build workflow. The whole process of doing this is explained nicely by Gouri in the article - Build Customization using Visual Studio 2010 – Part II.
Stage 3: We realize that the custom functionality that we want to execute as part of the build cannot be even composed of multiple XAML activities. Now is the time to extend what we have in TFS Build. We now write some code for the activity to execute the functionality that we have. Such custom activity is encapsulated in an assembly which is provided to designer as well as to the TFS. We can make use of that activity in a custom build process template and create a build definition based upon that template. When that build is executed, it will execute the custom code that we had written during the execution of workflow. You can find more about such Coded Custom Activity in this article written by Gouri - Build Customization using Visual Studio 2010 (TFS 2010) - Creating Custom Activity. A part of the case of organization ‘C’ is fulfilled in this stage. Which part? The one where they need to package and deploy the application on a staging server.
Stage 4: Now we are at a point where the functionality we want is already put in a tool by a third party. There is no point in reinventing the … OOP. We want to use that same tool as part of our build. There is an activity in the toolbox of the workflow designer that is called InvokeProcess activity. This activity is a gateway to call any command or a tool from build. So we drag and drop this InvokeProcess activity on the workflow designer at the appropriate place and provide the path of that third party tool as a property of that activity. We should also provide a property to hold the results of that tool when the activity executes. We can even base the outcome of build on the value that is returned by this tool. How to do all this? Explained in a great way by … who else, Gouri again in this article - VS 2010 Build Customization: Custom Activity Invoke Process. This stage takes care of the remaining requirement of Organization ‘C’ regarding build customization and extension.
The scope of this article has become too large and we have also exhausted the cases that we started with. By no means are the ways to extend TFS, exhausted. We can write any type of application like Windows App, Store App, Web App and even a mobile app written on Android. For the last bit about Android, check this article that I had written in the DNC magazine Creating Android Client for Team Foundation Server 2012. It uses another way to call TFS – OData!
For every type of client, there always is an appropriate solution to extend TFS! Happy Extending!