metro-binary-vb-128-link
 

Team Foundation Server 2010 Event Handling with Subscribers

Book an Expert

 

ConfigurationRequiredThere is a lot of references and blog posts on how to handle SOAP events raised by Team Foundation Server 2005, 2008 and 2010 but is there anything new in 2010 that supersedes this? Even though I knew it was there, n o amount of google-fu brought back any results relevant to anything new, so hopefully this will fill that gap.

 


In Team Foundation Server (TFS) 2010 you can write event subscribers that are called and run within the context of the TFS server itself. This means that you have access to all the goodies within TFS directly without having to call back to the TFS server.

This is the first proof-of-concept handler I have written in a process leading to rewriting the TFS Event Handler to use this method of handling events as it will be much slicker with the ability to write much more complex handlers.

In order for your new Event Handler to be loaded and run you need to put it somewhere that TFS knows to look. As TFS is primarily made up of a bunch of web services you would be putting any output assemblies into the “%Program Files%Microsoft Team Foundation Server 2010Application TierWeb ServicesbinPlugins” directory. TFS will look through any assemblies in this folder and load any classes that implement any of the extension interfaces.

In this case we are extending TFS using the ISubscriber interface.

The ISubscriber interface can be found in the “Microsoft.TeamFoundation.Framework.Server” assembly and gives you the basics for wiring up to a particular Event.

Once you have implemented the interface your method stubs will be created for you.

Although the name does not immediately look like it is useful I would assume that any error output would include the name as a reference so it would probably be best to pick something that is easily recognisable.

I am really not sure of the impact of changing the Priority, but I think it would influence the order in which any Subscribers are executed, with the higher priority subscribers getting first dibs. This would be important if we were implementing the Decision points ability that has been built into events.

Some of the events allow you to cancel or change the action mid stride. Think of cancelling a Check-in if your company policy is not met.

You can find a full list of events and which ones support Decision points on my previous post.

As the Subscribers can handle any type of event this is were you can start the filtering process and only have events you are interested in passed your way. This is also where you have to pull in other assemblies to reference the specific events as they are peppered all over the assemblies for TFS.

In this case we need to reference the “Microsoft.TeamFoundation.WorkItemTracking.Server.DataAccessLayer.dll” assembly as it contains the WorkItemChangedEvent under the “Microsoft.TeamFoundation.WorkItemTracking.Server” namespace. I am not really sure why it is hidden away in this assembly, but I think there were many things that were not finished before RTM and probably moving these classes did not make the cut.

All you need to do is pass back an array of the types of events you want to handle.

Now that we have told TFS what events we want to process when we implement the ProcessEvent method we can be reasonably certain that it is the right one, but it is always prudent to do an additional test so you don’t process any non event specific code by accident.

The requestContext has many of the options and information you will be familiar with on a TeamFoundationServer or TeamProjectCollection object, but without the thing that are really only relevant when you are accessing a remote server. This is an object with many properties and functions that will let you access almost any facet of your TFS server from security to version control.

The notification Type can be used to identify which call you want to handle. For those events that have a decision point as well ProcessEvent would likely be called twice, once for the decision and if the process is permitted to complete once for the notification.

Once you have completed any tasks that you want to action you would then pass back the ActionPermited by default. I am not sure yet of the implications of the other options, but all of the built in subscribers pass that back as the default so I will as well.

All I am doing here is writing an event received acknowledgements to a text file, but it is enough for me to prove that the event is captured. All I have to do is copy the assembly output to the right place and make a change to a work item.

SNAGHTMLf0653c

Figure: Putting the assembly in the right place is very strait forward

SNAGHTMLf22466

Figure: Make any sort of change to a work item and save it

Now lets look into the output file:

As you can see we received the event with our event receiver, handled it successfully and wrote some useless text to a file.

Conclusion

This is a heck of a lot easier than subscribing to events through web services, but you need access to the TFS server locally to be able to add the DLL’s. If you are looking for a zero touch approach you can achieve this through WCF web service soap calls from TFS, but if you want a little more intimacy and structure then you should be using server side events.

Which method will you be using?

 

Team Foundation Server 2010 Event Handling with Subscribers was last modified: September 16th, 2010 by Martin Hinshelwood

-Every company deserves working software that successfully and consistently meets their customers needs on a regular cadence. We can help you get working software with continuous feedback so that your lean-agile teams can deliver continuous value with Visual Studio ALM, Team Foundation Server & Scrum. We have experts on hand to help improve your process and deliver more value at higher quality.

  • 1015PED

    Thank for good tips

  • mirdin

    I tried to catch CheckinEvent and BuildcomplitionEvent using code like your but that events wasn’t catched. There was not any error but function ProcessEvent was not executed. Could you help me with this problem?

  • Nick Tulett

    Got this working after giving up on SOAP but I’m unsure where to go next. Where do I get the information I would have got from eventXML?

    i.e. how can I see which WI was changed and by whom?

    I am not VB literate, unfortunately…

  • Nick Tulett

    Ah, OK I just found your eventhandler stuff on codeplex, so I think I can follow it from there…

  • Nick Tulett

    Genuine question this time. I’ve added an email sender and it looks like ProcessEvent() gets fired 4 times for a single workitem change.

    Am I supposed to be monitoring some kind of EventComplete flag?

  • Nick Tulett

    Rewrote in C# and the multiple-fire problem went away…

  • Allen.Feinberg

    Good stuff. Now how can I hook up these changes so that they get emailed to people?

  • Ed Blankenship

    (Shameless plug…)

    I am happy to say that we are including some information about this topic in our new TFS 2010 book in case you are looking for more information!

    http://bit.ly/TFS2010Book

  • Subodh Sohoni

    Thanks Martin, Excellent stuff. After a long time I cam back to event handling and found this post. Gives me the right direction to work further.

  • Jordan

    I am looking for a way to send an email update to a list of people anytime a bug is updated. The list will vary for each bug, so I can’t hard code the names of the people. To accomplish this, I was considering creating a new field in the bug template where the users could enter in all the emails.

    I can see that by using your method of event handling, I could accomplish this relatively easily, but I have a question.

    Would this event be called along with the normal Work Item Changed event, or would it replace it. ex. If user A signs up for the “My Work Items Changed” event, and user A is also listed in my custom field, will he receive two emails, or just one?

    Thanks for the awesome idea.

  • Vaccano

    Thanks for the info. I was able to use this info to make my own aggregator code.

    I posted it on codeplex here: http://tfsaggregator.codeplex.com/ if any one else is interested

  • Tomas Lundström

    Great stuff, works well. However, I have found a couple of issues:
    * In my first attempt, the plugin threw an exception (I forgot to implement the Priority property). This caused the ENTIRE TFS to stop working!! So you better make sure your plugin is robust, because TFS is not …
    * Secondly: the WorkItemChangedevent provides the project name (aka PortfolioProject) but I cannot find a way to get the Collection name. How can I then deduce which project I am dealing with, since the same project name can exist in several Collections?

    Best regards,
    /Tomas

  • Richard Roberts

    Great information but I am getting exception errors when my component tries to access and read an element in a app.config file.ConfigurationManager.AppSettings[“somekey”]; Any Ideas why?

    Detailed Message: The subscriber WorkItemChangedEventHandler raised an exception while being notified of event Microsoft.TeamFoundation.WorkItemTracking.Server.WorkItemChangedEvent.Exception Message: Object reference not set to an instance of an object. (type NullReferenceException)Exception Stack Trace: at Rma.ReleaseManager.TFSEvents.DeploymentRequestClosed.DeploymentRequestClosedEventHandler.ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, Object notificationEventArgs, Int32& statusCode, String& statusMessage, ExceptionPropertyCollection& properties)at Microsoft.TeamFoundation.Framework.Server.TeamFoundationEventService.SubscriptionList.Notify(TeamFoundationRequestContext requestContext, NotificationType notificationType, Object notificationEventArgs, String& statusMessage, ExceptionPropertyCollection& properties)

  • Richard Roberts

    Again great information but, How do I invoke c# code while in transistion to another state? I have code I want to run to test related linked items.  These linked items are different type work items that have to be in the correct state and status in order for the parent work Item can be tranistioned from state A to State B.  In other words I want to be able to run my custom code if an error notifiy the user on the Work Item form that they need to perform some action to the related linked items before it can be transitioned into the next state.  In the full blown Workflow engine you can have an CodeActivty to invoke code.

    any thoughts or ideas?

  • Martin

    Hi geat stuf, but is there a possibility to load a referenced dll in the “ISubscriber-DLL” without adding the external dll to the GAC?

  • Pingback: TFS Server-side check-in policy for git repositories | Karsten Kempe – Visual Studio ALM()

  • Pingback: TFS Event Handler for Team Foundation Server | Cose inutili ma utili...()

  • Pingback: TFS Event Handler for Team Foundation Server - Microsoft Dynamics CRM Community()