<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://footheory.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Bennie&amp;#39;s Weblog</title><subtitle type="html" /><id>http://footheory.com/blogs/bennie/atom.aspx</id><link rel="alternate" type="text/html" href="http://footheory.com/blogs/bennie/default.aspx" /><link rel="self" type="application/atom+xml" href="http://footheory.com/blogs/bennie/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20611.960">Community Server</generator><updated>2007-07-25T20:38:49Z</updated><entry><title>Software as a Service - A high level overview</title><link rel="alternate" type="text/html" href="http://footheory.com/blogs/bennie/archive/2007/12/15/software-as-a-service-a-high-level-overview.aspx" /><id>http://footheory.com/blogs/bennie/archive/2007/12/15/software-as-a-service-a-high-level-overview.aspx</id><published>2007-12-15T22:13:27Z</published><updated>2007-12-15T22:13:27Z</updated><content type="html">&lt;h3&gt;Table of Contents&lt;/h3&gt; &lt;p&gt;Software as a service is a term is frequently making headlines in a number of trade journals. In all articles on the subject, Software as a Service is mentioned as the "next big thing", which is going to revolutionize the software industry as we know it.&lt;/p&gt; &lt;p&gt;This article will provide a high-level overview of the subject. The article structured as follows:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;In the first section we introduce Software as a Service (know by its acronym Saas), provide a definition and discuss some fundamental topics that form the basis for the technology. Also, since the concept of a "tenant" and "multi-tenancy" is closely associated with Saas, we will include a definition for these terms in the same section.&lt;/li&gt; &lt;li&gt;The next section will address how Saas can mitigate the software acquisition risks for an organization.&lt;/li&gt; &lt;li&gt;Often, a (false) rumor has been spread throughout the industry, that SaaS eliminates the need for an client organization's IT staff. In our next section, we clarify this misconception, and show how SaaS can empower an IT organization to focus on new initiatives that contribute measurable, immediate value to the client's organization.&lt;/li&gt; &lt;li&gt;Next, we discuss the three core attributes that are essential for an effective single instance, multi-tenant application architecture.&lt;/li&gt; &lt;li&gt;Four different maturity models have been defined for a multi-tenant SaaS application, our next section discusses these different maturity levels and their specifics.&lt;/li&gt; &lt;li&gt;In the last section of this article, I provide the reader with some guidance of how the select the appropriate maturity level for their organization's&amp;nbsp; Saas application(s).&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;This article is mostly non-technical is nature. However, I am planning to follow-up this article with a number of technical articles, where we dive into some of the more challenging areas that make it possible to create a highly scalable, configurable and multi-tenant-efficient SaaS solution.&lt;/p&gt; &lt;h3&gt;Introduction&lt;/h3&gt; &lt;p&gt;When you ask a number of software professionals for a definition of the term "Software as a Service", you will get many different, and sometimes conflicting answers. Slowly tough, more and more experts are starting to agree on the fundamental principles that define Software as a Service, and the concepts that differentiate the technology from traditional, on-premise packaged software solutions.&lt;/p&gt; &lt;p&gt;The current, widely-accepted definition for Software as a Service can best be phrased as follows:&lt;/p&gt; &lt;p align="center"&gt;&lt;em&gt;&lt;font size="3"&gt;&lt;strong&gt;Saas&lt;/strong&gt; is software deployed as a multi-tenant hosted service and accessed over the Internet.&lt;/font&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Saas should not be confused with the services provided by traditional Application Service Providers (ASPs). An ASP typically provides a "shrink-wrapped" application to business users over&amp;nbsp; the Internet, and therefore can be better compared with a traditional on-premise IT application which has been deployed and hosted by a third-party. These applications were architected as a single-tenant application, and were not designed to share data and business process logic with other applications. Since we used the term &lt;strong&gt;tenant&lt;/strong&gt; here I feel like another definition is in order:&lt;/p&gt; &lt;p align="center"&gt;&lt;em&gt;&lt;font size="3"&gt;A &lt;strong&gt;tenant&lt;/strong&gt; is a client organization, which is using an application that has been deployed as a SaaS Application.&lt;/font&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Multitenancy&lt;/strong&gt; refers to the architectural principle, in which a single instance of the software runs on as Software as a Service (SaaS) vendor's servers, servicing multiple client organizations (tenants). Multitenancy can be contrasted with a multi-instance architecture, where separate software instances (or hardware systems) are set up for different client organizations. With a multitenant architecture, a software application is designed to virtually partition its data and configuration so that each client organization works with a different virtual application instance.&lt;/p&gt; &lt;p&gt;A typical SaaS application is offered either directly by the vendor or by an intermediary party called an &lt;em&gt;aggregator&lt;/em&gt;, which bundles SaaS offerings from different vendors and offers them as part of a unified application platform.&lt;/p&gt; &lt;p&gt;I strongly believe that Saas is going to have a major impact on the software industry, because software as a service will change the way people build, sell, buy and use software. For this to happen though, software vendors need resources and information about developing Saas applications effectively.&lt;/p&gt; &lt;p&gt;When you take a look at our definition for Saas, it should become immediately clear that it does not prescribe any specific application architecture; it does not say anything about &lt;/p&gt; &lt;h3&gt;Saas and Software Acquisition Risk Mitigation&lt;/h3&gt; &lt;p&gt;Another area in which Saas applications tend to be different as compared to on-premise software is in their licensing model. On-Premise software applications typically have a high cost of entry, either because the application has to be developed from scratch by the internal or external IT staff, or in the case of a purchased application, because of the high up-front licensing fees. In contrast, SaaS application access is typically sold based upon a subscription model. The different subscription models offered by SaaS vendors are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A flat time-based fee (monthly, yearly etc.). This time-based fee will typically be much lower than the large up-front licensing fees for purchased on-premise applications.  &lt;li&gt;Usage based upon the metered activity by the customer, where 'usage activity' can be measured in a variety of ways, including number of business transactions, number of orders processed etc.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Some vendors will use a combination of both models, charging a flat time based fee in addition to some usage-based premium. In addition, most Saas vendors offer a "try before you buy" option, where a potential tenant has the opportunity to try out the application for a period of time before needing to make a commitment towards becoming a full-fledged customer.&lt;/p&gt; &lt;p&gt;In the traditional model, deploying large scale business-critical software systems (SAP anyone ? ;-) has been a major undertaking. As we mentioned earlier, deploying these systems across a large enterprise can cost hundred of thousands of dollars in up-front licensing cost, and usually requires a small (or sometimes large&amp;nbsp; ;-) army of IT personnel and consultants to customize and integrate it with with the organization's other systems and data. The time, staff and budget requirements of a deployment of this magnitude represents a significant risk for an organization of any size, and often puts such software out of reach of smaller organizations that would otherwise be able to derive great benefits&amp;nbsp; from the applications.&lt;/p&gt; &lt;p&gt;The subscription-based delivery model of SaaS applications changes this whole mindset. SaaS applications don't require the deployment of a large infrastructure at the customer's location, which eliminates or drastically reduces the upfront commitment of resources. With no significant initial investment to amortize, an enterprise that deploys a Saas application that turns out to produce disappointing results can walk away and pursue a different direction, without having to abandon an expensive on-premise infrastructure.&lt;/p&gt; &lt;h3&gt;Does Saas eliminate the need for an IT organization?&lt;/h3&gt; &lt;p&gt;One (wrong) conclusion that some people draw from the deployment of SaaS-based application is that it eliminates, or drastically reduces the need for an internal IT staff of an tenant's organization. Indeed with SaaS, the job of deploying&amp;nbsp; an application and keeping it running from day to day - testing and installing patches, managing upgrades, monitoring performance, ensuring high availability, and so forth - is handled by the provider.&lt;/p&gt; &lt;p&gt;But, rather than eliminating the need for an internal IT staff, by transferring the responsibility for the above-mentioned "overhead" activities to a third-party, the IT department can focus more on high-value activities that align with and support the business goals of the enterprise. Instead of being primarily reactive and operations-focused, the chief information offices (CIO) and IT staff can more efficiently function as technology strategists to the rest of the company, working with the business units to understand their business needs and advise them on how to best use technology to accomplish their objectives.&lt;/p&gt; &lt;p&gt;So, instead of being made obsolete by SaaS, the IT department has an opportunity to contribute to the success of the enterprise more directly than ever before. For example, based upon business requirements, the IT staff could create "composite applications" and "executive dashboards", which act as integrators and collectors of the valuable data contained in the different Saas applications. A successful service-centric IT organization can directly produce more value for the business by providing services that draw from both internal and external sources and align closely with the overall business goals of the organization.&lt;/p&gt; &lt;h3&gt;The Three Attributes of a Single Instance Multi-Tenant Architecture&lt;/h3&gt; &lt;p&gt;From an application's architect point of view, there are three key differentiators that separate a well-design SaaS application from a poorly designed one. A well-designed SaaS application is:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Scaleable  &lt;li&gt;Multi-Tenant-efficient  &lt;li&gt;Configurable&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;A graphical representation of these three important differentiators is shown below:&lt;/p&gt; &lt;p&gt;&lt;a title="SaasDifferentiators" href="http://www.flickr.com/photos/99548241@N00/2110675553/"&gt;&lt;img alt="SaasDifferentiators" src="http://static.flickr.com/2156/2110675553_9da266ae35.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Scaling the application means achieving maximum&amp;nbsp; concurrently and using application resources more efficiently - for example, optimizing locking duration, statelessness, efficiently leveraging sharing pooled resources&amp;nbsp; such as thread and network connections, caching frequently used reference data, and partitioning large databases. Note that I am not stating here that a standard single-tenant application should NOT be designed&amp;nbsp; in a scaleable manner, but because of the resource-intensive nature of a multi-tenant application, these requirements are more amplified, and achieving maximum scalability is therefore even more important.&lt;/p&gt; &lt;p&gt;Multi-tenancy may be the most significant paradigm shift that an architect accustomed to designing isolated, single-tenant applications has to make. For example, when a user at one company accesses customer information by using a CRM application (e.g. SalesForce.com), service, the application instance that the user connects to may be accommodating users from dozens, or even hundreds, of other companies - all completely unbeknownst to any of the users. This requires an architecture that maximizes the sharing of resources across tenants, but in such a manner that the application is still able to differentiate data belonging to different customers. For example, in a multi-tenant environment, it might be prohibitive to allocate an expensive resource, such as a WIN32 process to a single tenant (we will have more to say about this topic in the next section). Also, the architect needs to ensure 100% data privacy for each tenant while maintaining an acceptable performance for each tenant.&lt;/p&gt; &lt;p&gt;Of course, if a single application instance on a single server has to accommodate users from several different companies at once, you can't simply write custom code to customize the end-user experience; anything you do to customize the application for one customer will change the application for other customers as well. Instead of customizing the application in the traditional sense, each customer uses metadata to configure the way the application appears and behaves for its users. The challenge for the SaaS Architect is to ensure that the task of configuring applications is simple and easy for the customers, without incurring extra development or operation costs for each configuration. Note that configuration is this context can apply to a number of different areas:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Allowing tenants to add custom fields or tables to the database.  &lt;li&gt;Providing a mechanism by which a tenant can customize the user interface and the look and feel of the application (for example, in the case of a web application, the user should be able to upload custom a style sheet for the application).  &lt;li&gt;Allowing tenants to customize the business process workflows, by including some type of process editor in the tenant's administrator user interface.&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;Saas as a Service-Oriented Architecture Maturity Model&lt;/h3&gt; &lt;p&gt;In the above sections, we have discussed the business and technical benefits of Saas. The biggest impact of SaaS tough might be the fact that SaaS finally provides an organization with the right incentives for moving IT towards&amp;nbsp; a services-centric model or in other words: a "real", applied SOA strategy with concrete,&amp;nbsp; tangible benefits.&lt;/p&gt; &lt;p&gt;Broadly speaking, SaaS service maturity can be expressed using a model with four distinct levels. Each level is distinguished from the previous one by the addition of one of the three attributes listed above. A graphical level with the different maturity levels is shown below:&lt;/p&gt; &lt;p&gt;&lt;a title="Saas Overview" href="http://www.flickr.com/photos/99548241@N00/2109143971/"&gt;&lt;img alt="Saas Overview" src="http://static.flickr.com/2134/2109143971_d2aa19a768.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;h4&gt;&lt;/h4&gt; &lt;h4&gt;Maturity Level I : Ad Hoc / Custom&lt;/h4&gt; &lt;p&gt;The first level of maturity is similar to the traditional application service provider (ASP) model of software delivery, dating back to the 1990s. At this level, each customer (or tenant) has its own customized version of the hosted application, and runs its own instance of the application on the hosts's servers. Architecturally, software at this maturity level is very similar to traditionally-sold LOB (Line-of-Business) software, in that different clients within the organization connect to a single instance running on behalf of its other customers. Note that at this maturity level, application maintenance tends to be complication and time consuming. If a common bug is found, the fix has to be integrated into the code base for each different instance, and each instance has to be individually tested, validated and re-deployed.&lt;/p&gt; &lt;p&gt;Typically, traditional client-server applications can be moved to a SaaS model at the first level of maturity, with relatively little development effort, and without re-architecting the entire system from the ground up. Although this level offers few of the benefits of a fully mature Saas solution, it does allow vendors to reduce cost by consolidating server hardware and administration.&lt;/p&gt; &lt;h4&gt;Maturity Level II: Configurable&lt;/h4&gt; &lt;p&gt;At the second level of maturity, the vendor hosts a separate instance of the application for each customer (of tenant). Whereas in the first level each instance is individually customized for the tenant, at this level all instances use the same code implementation, and the vendor meets customer's needs by providing detailed configuration options that allow the customer to change how the application looks and behaves to its users. Despite being identical to one another at the code level, each instance remains wholly isolated from all others.&lt;/p&gt; &lt;p&gt;Moving to a single code base for all of a vendor's customers greatly reduces a Saas application's service requirements, because any changes made to the code base can be easily provided to&amp;nbsp; all of the vendor's customers at once, thereby eliminating the need to upgrade or slipstream individual customized instances. However, repositioning a traditional application as SaaS at the second maturity level can require significant more re-architecting than at the first level, if the application has been designed for individual customization rather than configuration metadata. Therefore, it is important to note that if an enterprise architect is architecting a new application, which might be initially be deployed as a single-tenant application, but has the potential to be migrated to a multi-tenant solution, it is recommended that you take a close look at the architecture of your application, and build in some of the core "enabling" building blocks that would enable you to move to a multi-tenant solution without re-architecting the entire application.&lt;/p&gt; &lt;p&gt;Similarly to the first maturity level, the second level requires that the vendor provide sufficient hardware and storage to support a potentially large number of application instances running concurrently.&lt;/p&gt; &lt;h4&gt;Maturity Level III: Configurable, Multi-Tenant-Efficient&lt;/h4&gt; &lt;p&gt; At the third level of maturity, the vendor runs a &lt;em&gt;single&lt;/em&gt; instance that serves every customer, with configurable metadata providing a unique user's experience and feature set for each one. Authorization and security policies ensure that each customer's data is kept separate from that of other customers; and, from the end user's perspective, there is no indication that the application instance is being shared among multiple tenants.&lt;/p&gt; &lt;p&gt;This approach eliminates the need to provide server space for as many instances as the vendor has customers, allowing for more more efficient use of computing resources that the second level, which translates directly into lower costs. A significant disadvantage of this approach is that the scalability of the application is limited. Unless partitioning is used to manage database performance, the application can be scaled only by moving it to a more powerful server (scaling up), until diminishing returns make it impossible to add more power cost-effectively.&lt;/p&gt; &lt;h4&gt;Maturity Level IV: Scalable, Configurable, Multi-Tenant-Efficient&lt;/h4&gt; &lt;p&gt; At the fourth and final level of maturity, the vendor hosts multiple customers on a load-balanced farm of identical instances, with each customer's kept separate, and with configurable metadata providing a unique user experience and feature set for each customer. A SaaS system is scalable to an arbitrarily large number of customers, because the number of servers and instances of the back end can be increased or decreased as necessarily to match demand, without requiring additional re-architecting of the application, and changes or fixes can be rolled out to thousands of tenants as easily as a single tenant.&lt;/p&gt; &lt;h3&gt;Selecting the Appropriate Maturity Level for your Application&lt;/h3&gt; &lt;p&gt;Given all of the above information, you might wonder what maturity level you should target for your SaaS application? Intuitively, one might expect the fourth level to be the ultimate goal for any SaaS application, but this is definitely not always the case. Indeed, it might be more helpful to think of SaaS maturity as a continuum between isolated data and code on one end, as shared data and code on the other, as is shown on the figure below:&lt;/p&gt; &lt;p&gt;&lt;a title="SelectingAMaturityModel" href="http://www.flickr.com/photos/99548241@N00/2113756924/"&gt;&lt;img height="136" alt="SelectingAMaturityModel" src="http://static.flickr.com/2409/2113756924_b64d3b8000.jpg" width="640" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Where your application should fall in this continuum depends on your business area, architectural experience and operational needs, and on customer considerations. As you'll be able to see event from this simple explanation, all of these considerations are interrelated to some degree.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Business Model.&lt;/strong&gt; Does an isolated approach make financial sense? Forsaking the economic and management benefits of a shared approach means offering your application to the consumer at a higher cost; however; under some circumstances, it may be worth it to meet other needs. In addition, customers might have strong legal (e.g HIPPAA for the health care industry) or cultural resistance to an architectural model in which multiple tenants share access to an application, even if you can demonstrated that it does not place confidential data at risk. Ultimately, of course, you'll need a business model that shows how your&amp;nbsp; application can make money at whichever maturity level you've targeted.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Architectural Model&lt;/strong&gt;. Can your application be made&amp;nbsp; to run in a single local instance, without a complete architectural overhaul? if you seeking to move a desktop-based or traditional client-server or distributed application to an Internet-based delivery system, then its architecture might be fundamentally incompatible with a single-instance, metadata-centric approach, and you may determine that it will never make financial sense to invest the development effort necessary to transform it into a fully mature SaaS application. If you are designing and building a net-native application from the ground up, you will probably have a lot more freedom to take a single-instance approach.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Operational Model&lt;/strong&gt;. Can you guarantee your service level agreements (SLAs) without isolation? You (and your legal department ;-) should carefully example the obligations imposed by any existing SLAs that you have with your existing customers, with regard to considerations such as downtime, support operations, and disaster recovery, and determine whether these obligations can be met under an application architecture in which multiple unrelated customers share access to a single application instance.&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;This concludes our high-level overview of SaaS. Obviously this is a very rich topic, but I hope that in the course of reading this article, you got a good basic understanding of what SaaS is, what its benefits are to an organization, the different maturity levels, and how to select a maturity level that is appropriate for your organization.&lt;/p&gt; &lt;p&gt;During the course of the coming week, I will be following up on this article with a more technical paper, which will describe some of the architectural challenges associated with building a single-instance, multi-tenant efficient and scalable application, so stay tuned!&lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=288" width="1" height="1"&gt;</content><author><name>bennie</name><uri>http://footheory.com/members/bennie.aspx</uri></author><category term="Saas" scheme="http://footheory.com/blogs/bennie/archive/tags/Saas/default.aspx" /><category term="Software as a Service" scheme="http://footheory.com/blogs/bennie/archive/tags/Software+as+a+Service/default.aspx" /></entry><entry><title>Team Foundation Server Extensibility - Navigating the Object Model</title><link rel="alternate" type="text/html" href="http://footheory.com/blogs/bennie/archive/2007/11/11/team-foundation-server-extensibility-navigating-the-object-model.aspx" /><id>http://footheory.com/blogs/bennie/archive/2007/11/11/team-foundation-server-extensibility-navigating-the-object-model.aspx</id><published>2007-11-12T01:16:50Z</published><updated>2007-11-12T01:16:50Z</updated><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt; &lt;p&gt;In my &lt;a href="http://footheory.com/blogs/bennie/archive/2007/11/07/an-introduction-to-team-foundation-server-extensibility.aspx" target="_blank"&gt;previous post&lt;/a&gt; I introduced Team Foundation Server's customization and extensibility features. I mentioned how the TFS core functionality is exposed by means of the &lt;strong&gt;Team Foundation Core Services&lt;/strong&gt; (TFCS), which are essentially a set of five different Web Services. The functionality of these web services is encapsulated by the &lt;strong&gt;Team Foundation Server Object Model&lt;/strong&gt; (TFSOM), which is what Microsoft recommends you use to implement a Team Foundation extension.&lt;/p&gt; &lt;p&gt;The Team Foundation Object Model is implemented in a series of assemblies, some of which we will take a detailed look at in this post. We will explore some of the core objects in this object model, and we will build a small wrapper class library, called &lt;font face="Courier New" size="2"&gt;FooTheory.TFS.TFSConnectivity.&lt;/font&gt; We will use this class library as our foundation to create the following custom extensibility clients:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;A PowerShell &lt;font face="Courier New" size="2"&gt;PSDrive&lt;/font&gt; provider called &lt;font size="3"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;FooTheory.TFS.TFSProvider&lt;/font&gt;.&lt;/font&gt;&lt;/font&gt; This provider will allows us to treat the TFS repository as a logical drive, so we will be able to use our favorite commands such as&amp;nbsp; &lt;font face="Courier New" size="2"&gt;dir, cd, copy, new &lt;/font&gt;(or their "offical"cmdlet names: &lt;font face="Courier New" size="2"&gt;Get-ChildItems, Set-Location, Copy-Item, New-Item&lt;/font&gt;)&amp;nbsp; to manipulate TFS artifacts such as Work Items, Stored Queries, Team Projects, Reports etc.&lt;/li&gt; &lt;li&gt;An event listener called FooTheory.TFS.EventListener. This is a WCF-based service, which can subscribe to TFS events, and receive these events through HTTP. The other clients, such as the PSDrive provider and the WPF client will be able to host this service, enabling them to be informed of any changes to their TFS artifacts of interest.&lt;/li&gt; &lt;li&gt;A rich WPF-based client called FooTheory.TFS.TFSExplorer. This client will take full advantage of the graphical expressiveness of Windows Presentation foundation to allow the user to navigate the complete TFS object model, including Work Items, Reports, Source Code trees etc.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt; An overview of the assemblies is shown in the figure below:&lt;/p&gt; &lt;p&gt;&lt;a title="MainLayers" href="http://www.flickr.com/photos/99548241@N00/2048565987/"&gt;&lt;img alt="MainLayers" src="http://static.flickr.com/2001/2048565987_a033cb8b3e.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To start out, we will take a look at the TFSOM client assemblies which need to reference in our class library in order to implement our functionality.&lt;/p&gt; &lt;h2&gt;TFSOM Client Assemblies&lt;/h2&gt; &lt;p&gt;To leverage the functionality of the TFSOM, we need references to the following assemblies:&lt;/p&gt; &lt;p&gt;&lt;a title="DllOverview" href="http://www.flickr.com/photos/99548241@N00/2049299808/"&gt;&lt;img alt="DllOverview" src="http://static.flickr.com/2293/2049299808_12902cc342.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;If you have Team Explorer installed on your client, these assemblies should be located in the &lt;font face="Courier New" size="2"&gt;C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies&lt;/font&gt; location, together with all of the TFSOM assemblies. (If you have Orcas installed, you need to substitute "&lt;font face="Courier New" size="2"&gt;Visual Studio 9&lt;/font&gt;" for "&lt;font face="Courier New" size="2"&gt;Visual Studio 8&lt;/font&gt;" in the above path). Also, if you have Team Foundation Server 2008 installed, these assemblies will be the client assemblies for the Team TFS 2008, but these assemblies are 100% backwards compatible with TFS 2005 object model, so you can use the same assemblies to access both TFS versions.&lt;/p&gt; &lt;p&gt;In the next section we will take a look at the high-level design of our &lt;font face="Courier New" size="2"&gt;FooTheory.TFs.TFSConnnectivity&lt;/font&gt; custom class library.&lt;/p&gt; &lt;h3&gt;The FooTheory.TFS.TFSConnectivity assembly&lt;/h3&gt; &lt;p&gt;The main goal behind creating this assembly is to provide a simple API that provides access to some of the core functionality that we need to implement, for example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Connecting and authenticating to a Team Foundation Server Instance.  &lt;li&gt;Retrieving a list of all Team Projects .  &lt;li&gt;Retrieve the Process Template of a given Team Project instance.  &lt;li&gt;Retrieving the Microsoft Project mapping properties for a Team Project instance.  &lt;li&gt;Subscribing and unsubscribing to a TFS Event Type.  &lt;li&gt;Retrieving all stored Work Item Queries for a given project.  &lt;li&gt;Executing a stored query, retrieving the resulting Work Items in the process.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The main class in our assembly is the &lt;font face="Courier New" size="2"&gt;FooTheory.TFS.TFSConnectivity.TFSServer&lt;/font&gt; class. An overview class diagram of this class and its main relationships is shown in the figure below:&lt;/p&gt; &lt;p&gt;&lt;a title="Overview" href="http://www.flickr.com/photos/99548241@N00/2049427358/"&gt;&lt;img alt="Overview" src="http://static.flickr.com/2055/2049427358_0faf3c1b9f.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;font face="Courier New" size="2"&gt;FooTheory.TFS.TFSConnectivity.dll&lt;/font&gt; assembly uses the Patterns &amp;amp; Practices Enterprise Library 3.1. Specifically, it leverages the &lt;font face="Courier New" size="2"&gt;Logging&lt;/font&gt; and &lt;font face="Courier New" size="2"&gt;Exception Handling &lt;/font&gt;blocks to enhance the robustness of the assembly. We'll have a few words to say about our usage of the Enterprise library at the end of this post.&lt;/p&gt; &lt;p&gt;Next, we will take a more detailed look at the class that is at the center of the Team Foundation Server Object Model, the &lt;font face="Courier New" size="2"&gt;Microsoft.TeamFoundation.Client.TeamFoundationServer &lt;/font&gt;class.&lt;/p&gt; &lt;p&gt;After we have a better understanding of this class, we will use our understanding of the &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; class to design and implement our &lt;font face="Courier New" size="2"&gt;TFSConnectivity&lt;/font&gt; assembly.&lt;/p&gt; &lt;h3&gt;The TeamFoundationServer Object&lt;/h3&gt; &lt;p&gt;The &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; object is the core object of the TFSOM. It contains the basic attributes of the Team Foundation Server that it is connected to. In addition, It provides access to the Team Foundation Core Services, as well as any other services that have been registered with Team Foundation Server, such as:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Version Control  &lt;li&gt;Work Item Tracking  &lt;li&gt;Project Templates  &lt;li&gt;Event subscriptions&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The &lt;font face="Courier New"&gt;TeamFoundationServer&lt;/font&gt; object is defined in the &lt;font face="Courier New" size="2"&gt;Microsoft.TeamFoundation.Client&lt;/font&gt; namespace, so you will need to have a reference to the &lt;font face="Courier New" size="2"&gt;Microsoft.TeamFoundation.Client.dll&lt;/font&gt; if your want to use it in your code.&lt;/p&gt; &lt;p&gt;You can get a reference to a &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; instance in one of two ways:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;You can use the &lt;font face="Courier New" size="2"&gt;TeamFoundationFactory.GetServer()&lt;/font&gt; method. This is the most commonly used strategy to create a &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; instance. The &lt;font face="Courier New" size="2"&gt;GetServer()&lt;/font&gt; method of the &lt;font face="Courier New" size="2"&gt;TeamFoundationServerFactory&lt;/font&gt; class supports the following overloads:  &lt;ul&gt; &lt;li&gt;You can only pass in the name of the server:&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;blockquote&gt; &lt;div&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; TeamFoundationServer GetServer(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; name);&lt;/pre&gt;&lt;/div&gt;&lt;pre class="csharpcode"&gt;You can pass in the name of the TFS server and an object that implements the &lt;font face="Courier New" size="2"&gt;ICredentialsProvider&lt;/font&gt;&amp;nbsp; interface:&lt;/pre&gt;
&lt;div&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; TeamFoundationServer GetServer(
            &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; name, ICredentialsProvider fallbackCredentialsProvider)&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;pre class="csharpcode"&gt;You can also choose to call the &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; constructor directly. The different overloads are shown below:&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;div&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TeamFoundationServer(String name);
&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TeamFoundationServer(
    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; name,
    ICredentials credentials);
&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TeamFoundationServer(
    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; name,
    ICredentialsProvider credentialsProvider);
&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TeamFoundationServer(
    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; name,
    ICredentials credentials,
    ICredentialsProvider credentialsProvider);
&lt;/pre&gt;&lt;/div&gt;&lt;pre class="csharpcode"&gt;The main difference between these two approaches is the fact that the Factory method caches the instance by the Uri of the server. The first time you call &lt;font face="Courier New" size="2"&gt;GetServer()&lt;/font&gt; with a specific server Uri, the factory will create a new &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; instance, add&amp;nbsp; it to cache (indexed by the server Uri) and return it to the caller. The next time you call &lt;font face="Courier New" size="2"&gt;GetServer()&lt;/font&gt; with the same server Uri (regardless of the &lt;font face="Courier New"&gt;ICredentialsProvider&lt;/font&gt; that is passed in), you will get exactly the same Uri instance. &lt;/pre&gt;
&lt;p&gt;The &lt;font face="Courier New"&gt;TeamFoundationServerFactory&lt;/font&gt; class was initially created to support the behavior of Team Explorer. In Team Explorer, you will notice that you will get the authentication dialog the first time your bring up the Explorer, but afterwards you are no longer prompted although behind the scenes, the team explorer code might have to call the Factory's &lt;font face="Courier New" size="2"&gt;GetServer()&lt;/font&gt; method multiple times. But, since the code is calling the &lt;font face="Courier New" size="2"&gt;GetServer()&lt;/font&gt; method with the same server Uri each time, you will NOT be prompted again.&lt;/p&gt;
&lt;p&gt;When you call the &lt;font face="Courier New"&gt;TeamFoundationServer&lt;/font&gt; constructor directly, you are obviously creating a new instance each time.&lt;/p&gt;
&lt;p&gt;As far as passing in credentials, you have basically two choices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can pass in a reference to an object that implements the &lt;font face="Courier New" size="2"&gt;ICredentialsProvider&lt;/font&gt; interface. While you can pass in any instance that implements this interface, in a UI-based scenario you probably would want to use Microsoft.TeamFoundation.Client.UICredentialsProvider class. When you create a new instance of this class, it will automatically pop up the authentication dialog. So the following code:&lt;/li&gt;&lt;/ul&gt;&lt;pre class="code"&gt;                &lt;span&gt;// Create an instance of the UICredentialsProvider.
&lt;/span&gt;                &lt;span&gt;// Note that creating this instance will automatically
&lt;/span&gt;                &lt;span&gt;// popup the TFS authentication dialog
&lt;/span&gt;                &lt;span&gt;ICredentialsProvider&lt;/span&gt; provider = &lt;span&gt;new&lt;/span&gt; &lt;span&gt;UICredentialsProvider&lt;/span&gt;();&lt;/pre&gt;
&lt;ul&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Will popup the following dialog:&lt;/p&gt;
&lt;p&gt;&lt;a title="TFSLogindialog" href="http://www.flickr.com/photos/99548241@N00/1973822715/"&gt;&lt;img alt="TFSLogindialog" src="http://static.flickr.com/2087/1973822715_177fa99583.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;You can pass in any &lt;font face="Courier New" size="2"&gt;NetworkCredential&lt;/font&gt; instance, for example:&lt;/li&gt;&lt;/ul&gt;&lt;pre class="code"&gt;                &lt;span&gt;// Create our Network Credentials
&lt;/span&gt;                &lt;span&gt;NetworkCredential&lt;/span&gt; credentials = &lt;span&gt;new&lt;/span&gt; &lt;span&gt;NetworkCredential&lt;/span&gt;(TFSUserName, TFSPassword);
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;h3&gt;Implementation in the FooTheory.TFS.TFSConnectivity Library&lt;/h3&gt;
&lt;h4&gt;Connecting to Team Foundation Server&lt;/h4&gt;
&lt;p&gt;The &lt;font face="Courier New" size="2"&gt;FooTheory.TFS.TFSConnectivity.TFSServer&lt;/font&gt; class contains an embedded instance of a &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; instance in the &lt;font face="Courier New"&gt;m_tfsServer&lt;/font&gt; field, and exposed through the &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; property:&lt;/p&gt;&lt;pre class="code"&gt;        &lt;span&gt;// This is our Team Foundation Server instance
&lt;/span&gt;        &lt;span&gt;private&lt;/span&gt; &lt;span&gt;TeamFoundationServer&lt;/span&gt; m_tfsServer;

        &lt;span&gt;///&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;summary&amp;gt;
&lt;/span&gt;        &lt;span&gt;///&lt;/span&gt;&lt;span&gt; This read-only property returns our current
&lt;/span&gt;        &lt;span&gt;///&lt;/span&gt;&lt;span&gt; TeamFoundationServer instance
&lt;/span&gt;        &lt;span&gt;///&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;/summary&amp;gt;
&lt;/span&gt;        &lt;span&gt;public&lt;/span&gt; &lt;span&gt;TeamFoundationServer&lt;/span&gt; TeamFoundatonServer
        {
            &lt;span&gt;get&lt;/span&gt; { &lt;span&gt;return&lt;/span&gt; m_tfsServer; }
        }
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The &lt;font face="Courier New" size="2"&gt;TFSServer&lt;/font&gt; class offers three overloads for the &lt;font face="Courier New" size="2"&gt;Connect()&lt;/font&gt; method, as shown below:&lt;/p&gt;&lt;pre class="code"&gt;        &lt;span&gt;public&lt;/span&gt; &lt;span&gt;bool&lt;/span&gt; Connect(&lt;span&gt;string&lt;/span&gt; serverName)
&lt;/pre&gt;&lt;pre class="code"&gt;        &lt;span&gt;public&lt;/span&gt; &lt;span&gt;bool&lt;/span&gt; Connect(&lt;span&gt;string&lt;/span&gt; serverName, &lt;span&gt;NetworkCredential&lt;/span&gt; credentials)
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;pre class="code"&gt;        &lt;span&gt;public&lt;/span&gt; &lt;span&gt;bool&lt;/span&gt; Connect(&lt;span&gt;string&lt;/span&gt; serverName, &lt;span&gt;ICredentialsProvider&lt;/span&gt; credentialsProvider)
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;The first overload does not take any type of credentials, and will use the &lt;font face="Courier New" size="2"&gt;UICredentialsProvider&lt;/font&gt; to pop up the connect dialog shown in the previous section. The other overloads either take a &lt;font face="Courier New" size="2"&gt;NetworkCredential&lt;/font&gt; or an object that implements &lt;font face="Courier New" size="2"&gt;ICredentialsProvider&lt;/font&gt;. After successfully connecting and authenticating, a reference to the &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; object instance is stored in the &lt;font face="Courier New" size="2"&gt;m_tfsServer&lt;/font&gt; field.&lt;/p&gt;
&lt;p&gt;The full implementations of the different &lt;font face="Courier New" size="2"&gt;Connect&lt;/font&gt; methods is shown below:&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// This overload of the Connect Method will prompt&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// the users for a set of credentials, by means of the&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// UICredentialsProvider. It then calls our "generic"&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// connect method, which takes an ICredentialsProvider&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// as its second argument&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;param name="serverName"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Connect(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; serverName)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  12:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Tracer(LoggingCategoryConstant.TFS_CONNECTIVITY_CONNECT))&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  13:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  14:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;//  Create an instance of our Creditials by means of the&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  15:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;//  UICredentialsProvider. Since we are using the &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  16:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;//  UICredentialsProvider here, this  method will popup &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  17:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;//  an authentication dialog for us and create a set &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  18:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;//  of Credentials for us, which are passed to our other &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  19:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;//  Connect overload that takes a generic &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  20:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;//  ICredentialsProvider argument&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  21:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// Create an instance of the UICredentialsProvider.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  22:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// Note that creating this instance will automatically&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  23:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// popup the TFS authentication dialog&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  24:&lt;/span&gt;         ICredentialsProvider provider = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UICredentialsProvider();&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  25:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Connect(serverName, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UICredentialsProvider());&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  26:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  27:&lt;/span&gt; } &lt;span style="color:#008000;"&gt;// method Connect&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  28:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  29:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  30:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// This overload of the Connect Method takes a NetworkCredential.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  31:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// This method is typically used from a server client, which does&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  32:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// not have the possibility to prompt the client for a username/password&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  33:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  34:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;param name="serverName"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  35:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;param name="credentials"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  36:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  37:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Connect(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; serverName, NetworkCredential credentials)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  38:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  39:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Tracer(LoggingCategoryConstant.TFS_CONNECTIVITY_CONNECT))&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  40:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  41:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;//  Log our parameters&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  42:&lt;/span&gt;         addLogEntry(&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  43:&lt;/span&gt;             LoggingCategoryConstant.TFS_CONNECTIVITY_TRACE,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  44:&lt;/span&gt;             &lt;span style="color:#006080;"&gt;"Connect method with ServerName and Credentials Called"&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  45:&lt;/span&gt;             EventIdentifier.ConnectToTfs,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  46:&lt;/span&gt;             EventPriority.StandardPriority,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  47:&lt;/span&gt;             TraceEventType.Verbose,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  48:&lt;/span&gt;             createCredentialsContextInfo(serverName, credentials));&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  49:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  50:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// Create our Network Credentials&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  51:&lt;/span&gt;         NetworkCredential credentials = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; NetworkCredential(TFSUserName, TFSPassword);&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  52:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  53:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// Here, we can pass the network credentials directly to the&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  54:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// TeamFoundationServer constructor, so we have no need to used&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  55:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// the factory here. You cannot use the factory methods with any &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  56:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// object instance that implements ICreditials, but it is supported&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  57:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// in the standard constructor, as we are using it here&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  58:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  59:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  60:&lt;/span&gt;             m_tfsServer = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TeamFoundationServer(serverName, credentials);&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  61:&lt;/span&gt;             m_tfsServer.Authenticate();&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  62:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  63:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;//  If we succcessfully authenticated, we can go ahead an extract&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  64:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;//  some reference to some commonly used service interfaces&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  65:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (m_tfsServer.HasAuthenticated)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  66:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  67:&lt;/span&gt;                 extractServiceInterfaces();&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  68:&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  69:&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  70:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (Exception ex)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  71:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  72:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; rethrow = ExceptionPolicy.HandleException(ex, ExceptionPolicyName.EXTERNAL_LIBRARY_POLICY);&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  73:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (rethrow)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  74:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  75:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  76:&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  77:&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  78:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  79:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  80:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Return the authentication status&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  81:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; m_tfsServer.HasAuthenticated;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  82:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  83:&lt;/span&gt; } &lt;span style="color:#008000;"&gt;// method Conection&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  84:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  85:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  86:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// This is our "generic" Connect method. This method takes any object &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  87:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// instance that implements ICredentialsProvider. It uses the &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  88:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// TeamFoundationServerFactory GetServer method to retrieve the &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  89:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// TeamFoundationServer implementation&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  90:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  91:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;param name="serverName"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  92:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;param name="credentialsProvider"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  93:&lt;/span&gt; &lt;span style="color:#008000;"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  94:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Connect(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; serverName, ICredentialsProvider credentialsProvider)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  95:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  96:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Tracer(LoggingCategoryConstant.TFS_CONNECTIVITY_CONNECT))&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  97:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  98:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;//  Log our parameters&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  99:&lt;/span&gt;         addLogEntry(&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 100:&lt;/span&gt;             LoggingCategoryConstant.TFS_CONNECTIVITY_TRACE,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 101:&lt;/span&gt;             &lt;span style="color:#006080;"&gt;"Connect method with ServerName and Credentials Called"&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 102:&lt;/span&gt;             EventIdentifier.ConnectToTfs,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 103:&lt;/span&gt;             EventPriority.StandardPriority,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 104:&lt;/span&gt;             TraceEventType.Verbose,&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 105:&lt;/span&gt;             createCredentialsContextInfo(serverName, credentialsProvider));&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 106:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 107:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// Create a TeamFoundationServer instance through the factory,&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 108:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// and authenticate&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 109:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 110:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 111:&lt;/span&gt;             m_tfsServer =&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 112:&lt;/span&gt;                 TeamFoundationServerFactory.GetServer(serverName, credentialsProvider);&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 113:&lt;/span&gt;             m_tfsServer.Authenticate();&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 114:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 115:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;//  If we succcessfully authenticated, we can go ahead an extract&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 116:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;//  some reference to some commonly used service interfaces&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 117:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (m_tfsServer.HasAuthenticated)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 118:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 119:&lt;/span&gt;                 extractServiceInterfaces();&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 120:&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 121:&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 122:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (Exception ex)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 123:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 124:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; rethrow = ExceptionPolicy.HandleException(ex, ExceptionPolicyName.EXTERNAL_LIBRARY_POLICY);&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 125:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (rethrow)&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 126:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 127:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 128:&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 129:&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 130:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 131:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 132:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Return the authentication status&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 133:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; m_tfsServer.HasAuthenticated;&lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 134:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, 'Courier New', courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt; 135:&lt;/span&gt; } &lt;span style="color:#008000;"&gt;// method Connect&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The first connect method uses the &lt;font face="Courier New" size="2"&gt;UICredentialsProvider&lt;/font&gt; class to retrieve the credentials from the user, and then calls the third overload of the &lt;font face="Courier New"&gt;Connect()&lt;/font&gt; method, which uses the &lt;font face="Courier New" size="2"&gt;TeamFoundationFactory.GetServer()&lt;/font&gt; method to connect to the Server, and the&lt;font face="Courier New" size="2"&gt; TeamFoundationServer'&lt;/font&gt;s &lt;font face="Courier New" size="2"&gt;Authenticate()&lt;/font&gt; method to authenticate with the server.&lt;/p&gt;
&lt;p&gt;The second &lt;font face="Courier New" size="2"&gt;Connect()&lt;/font&gt; overload accepts a &lt;font face="Courier New" size="2"&gt;NetworkCredential&lt;/font&gt;. Since the factory does not have an overload that takes an object that implement &lt;font face="Courier New" size="2"&gt;ICredentials&lt;/font&gt;, this method directly calls the &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; constructor, which does have an overload that accepts an &lt;font face="Courier New" size="2"&gt;ICredentials&lt;/font&gt; object instance.&lt;/p&gt;
&lt;p&gt;Also, note that after successfully connecting and authenticating to the TFS server, all overloads call the extractServiceInterfaces() private method. This method extracts all relevant service interfaces from the TeamFoundationServer instance, and cache them as fields of the class, as is shown below:&lt;/p&gt;&lt;pre class="code"&gt;        &lt;span&gt;///&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;summary&amp;gt;
&lt;/span&gt;        &lt;span&gt;///&lt;/span&gt;&lt;span&gt; This method extract our most commonly used service interface
&lt;/span&gt;        &lt;span&gt;///&lt;/span&gt;&lt;span&gt; from the TFS Server instance, and caches them in our private
&lt;/span&gt;        &lt;span&gt;///&lt;/span&gt;&lt;span&gt; fields
&lt;/span&gt;        &lt;span&gt;///&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;/summary&amp;gt;
&lt;/span&gt;        &lt;span&gt;private&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; extractServiceInterfaces()
        {
            &lt;span&gt;if&lt;/span&gt; (m_tfsServer != &lt;span&gt;null&lt;/span&gt;)
            {
                m_commonStructureSvc = (&lt;span&gt;ICommonStructureService&lt;/span&gt;)m_tfsServer.GetService(&lt;span&gt;typeof&lt;/span&gt;(&lt;span&gt;ICommonStructureService&lt;/span&gt;));
                m_workItemStore = (&lt;span&gt;WorkItemStore&lt;/span&gt;)m_tfsServer.GetService(&lt;span&gt;typeof&lt;/span&gt;(&lt;span&gt;WorkItemStore&lt;/span&gt;));
                m_processTemplateSvc = (&lt;span&gt;IProcessTemplates&lt;/span&gt;)m_tfsServer.GetService(&lt;span&gt;typeof&lt;/span&gt;(&lt;span&gt;IProcessTemplates&lt;/span&gt;));
                m_eventService = (&lt;span&gt;IEventService&lt;/span&gt;)m_tfsServer.GetService(&lt;span&gt;typeof&lt;/span&gt;(&lt;span&gt;IEventService&lt;/span&gt;));
            }
        } &lt;span&gt;// method extractServiceInterfaces&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Note how we use the &lt;font face="Courier New" size="2"&gt;GetService(typeof(xxx))&lt;/font&gt; pattern to retrieve each interface and/or object references (only the &lt;font face="Courier New" size="2"&gt;WorkItemStore&lt;/font&gt; is a object reference, all the others are interface references).&lt;/p&gt;
&lt;h4&gt;Retrieving Project Information&lt;/h4&gt;
&lt;p&gt;... coming soon ... &lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=213" width="1" height="1"&gt;</content><author><name>bennie</name><uri>http://footheory.com/members/bennie.aspx</uri></author></entry><entry><title>An Introduction to Team Foundation Server Extensibility</title><link rel="alternate" type="text/html" href="http://footheory.com/blogs/bennie/archive/2007/11/07/an-introduction-to-team-foundation-server-extensibility.aspx" /><id>http://footheory.com/blogs/bennie/archive/2007/11/07/an-introduction-to-team-foundation-server-extensibility.aspx</id><published>2007-11-08T04:28:34Z</published><updated>2007-11-08T04:28:34Z</updated><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt; &lt;p&gt;A large number of developers are using &lt;a href="http://msdn2.microsoft.com/en-us/teamsystem/aa718825.aspx" target="_blank"&gt;Team Foundation Server&lt;/a&gt; for a variety of tasks such as Source Control, Bug Tracking, Requirements gathering, running nightly builds and managing the overall life cycle of a software development project.&lt;/p&gt; &lt;p&gt;Visual Studio Team System provides rich integration&amp;nbsp;with Team Foundation Server through &lt;a href="http://msdn2.microsoft.com/en-us/teamsystem/bb496794.aspx" target="_blank"&gt;Team Explorer&lt;/a&gt;, which provides the basic connectivity to TFS. Users can use&amp;nbsp;Source Control Management to manage their source code, manage Work Items, create&amp;nbsp;Build types,&amp;nbsp;run Unit Tests and Load Tests, run one of many SQL Server 2005 Reporting Services-based Team Reports etc.&lt;/p&gt; &lt;p&gt;In addition to Visual Studio, Office 2003 and Office 2007 also offer direct or indirect connectivity to Team Foundation Server. You can have Work Items show up as Tasks in Outlook 2007, you can export a Microsoft Project 2003 schedule to TFS, creating Work Items&amp;nbsp;in the process, or you can export and import your Work Items to and from Excel 2007.&lt;/p&gt; &lt;p&gt;Even if you are working outside of the realm of the &amp;nbsp;.NET and the Microsoft development platform, you can use the &lt;a href="http://www.teamprise.com/" target="_blank"&gt;TeamPrise&lt;/a&gt; plug-in for Eclipse to provide connectivity from your favorite Java development environment to Team Foundation Server.&lt;/p&gt; &lt;p&gt;What a lot of people don't realize is that Team Foundation Server also offers a&amp;nbsp;powerful development object model, empowering the developer to create custom development tools, specialized clients, custom WebParts for a Team Project SharePoint portal&amp;nbsp;and so on. Team Foundation Server was developed from the ground up with extensibility in mind. Indeed, TFS itself is build upon&amp;nbsp;the &lt;strong&gt;Team Foundation Core Services&lt;/strong&gt;, which are a set of Web Services used by Team Foundation Server itself to implement&amp;nbsp;the different functional areas&amp;nbsp;for Team Foundation Server.&lt;/p&gt; &lt;p&gt;As a developer, you will seldom have a reason to directly use the Team Foundation Core services. Indeed, Microsoft created the &lt;strong&gt;Team Foundation Server Object Model&amp;nbsp;&lt;/strong&gt;to&amp;nbsp;increase the productivity&amp;nbsp;of the TFS developer.&amp;nbsp;The classes in this object model interact with the Web Services of the&amp;nbsp;Team Foundation Server Core Services and make it easy for you to&amp;nbsp;extend the functionality&amp;nbsp;of Team Foundation Server in one of the following&amp;nbsp;ways:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Create a custom TFS command-line tool.  &lt;li&gt;Develop custom PowerShell cmdlets or PowerShell PSDrive&amp;nbsp;providers that allow you to directly navigate the TFS repository.  &lt;li&gt;Develop a SmartClient or Web client for Team Foundation Server.  &lt;li&gt;Develop a custom check-on policy for your development team  &lt;li&gt;Create a &amp;nbsp;plug-in for&amp;nbsp;a third-party development tool.  &lt;li&gt;Create a custom SharePoint WebPart for your Team Project SharePoint portal.  &lt;li&gt;Implement custom Contiguous Integration (CI)&amp;nbsp;tools.  &lt;li&gt;Create new Team Foundation build tasks.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In article&amp;nbsp;two of this series we will create a custom class library, which will directly interface with the Team Foundation Object Model. We will create a set of Units Tests for the classes and methods in this library, and we will create a simple console client to navigate the object model.&lt;/p&gt; &lt;p&gt;In part&amp;nbsp;two of this article series, we will create a custom PowerShell &lt;font face="Courier New" size="2"&gt;PSDrive&lt;/font&gt; provider for TFS. This provider will allow us to navigate through the different artifacts in the TFS database, as if they were files and directories in the file system. We will be able to use the standard&lt;font face="Courier New" size="2"&gt; dir, cd, type&lt;/font&gt; etc. alias commands, together with the standard &lt;font face="Courier New" size="2"&gt;Get-ChildItem, Set-Location, Get-Content&lt;/font&gt;, etc..&amp;nbsp;&amp;nbsp;PowerShell cmdlets&amp;nbsp;to navigate&amp;nbsp;the TFS structure. The implementation of this provider will leverage the class library that we create in this post.&lt;/p&gt; &lt;p&gt;In the final post of this series, we will build a custom WPF client for Team Foundation Server, which will allow us to browse, edit and create Team Projects and Work Items. In the course of implementing this client, we will have an opportunity to dive into some interesting WPF features, such as data binding, data templates and control templates. We will also leverage the TFS eventing service to keep our UI synchronized with the TFS repository at all times.&lt;/p&gt; &lt;h3&gt;Extensibility versus Customization&lt;/h3&gt; &lt;p&gt;Before we dive into the details of the TFS extensibility model, I would like to clarify some terms that tend to lead to confusion in the community. These terms are:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Customization&lt;/strong&gt;. Customization involves modifying your environment, such as Visual Studio Team System or Team Foundation Sever, using the tools that are provided to you by that environment. It is important to note that there&amp;nbsp;is no real coding involved in customization. Indeed, before you go fire up Visual Studio to write custom code to perform a certain task, I would encourage you to check out the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2aed0ecc-1552-49f1-abe7-4905155e210a&amp;amp;displaylang=en" target="_blank"&gt;Team Foundation Administrator's Guide&lt;/a&gt; in the Team Foundation Help documentation. In a lot of cases, you will notice that you can customize your TFS environment by using the existing toolset, or by simply modifying&amp;nbsp;one or more of XML files. Also, I would encourage you to download the &lt;a href="http://msdn2.microsoft.com/en-us/teamsystem/aa718351.aspx" target="_blank"&gt;Team Foundation Server Power Toys&lt;/a&gt;, which extend the reach of the existing TFS toolset even further. Customization might include:  &lt;ul&gt; &lt;li&gt;Modifying a Process Template.  &lt;li&gt;Creating a new Work Item Type.  &lt;li&gt;Customizing Team Foundation Build.  &lt;li&gt;Modifying the Project Portal Template  &lt;li&gt;Turning check-in policies on or off.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;. Extensibility is concerned with adding new functionality to your environment, which typically does involve coding. You can extend a Team Foundation Server installation by writing code to access the Team Foundation Server object model.&amp;nbsp;This way you can build add-ins and integration components that round out the Team Foundation Server product line. TFS Extensions are typically created by internal IT departments or third-party independent software vendors (ISV's). Some extensibility examples are:  &lt;ul&gt; &lt;li&gt;An adapter that integrates an existing toolset with Team Foundation Server. A good example is the &lt;a href="http://www.teamprise.com/" target="_blank"&gt;TeamPrise&lt;/a&gt; plug-in for the Java Eclipse development environment. &lt;li&gt;A Customized Team Foundation Server development solution for a vertical industry (for example Healthcare-specific process templates, new Work Item Types with Healthcare-specific workflows etc.). &lt;li&gt;Custom explorer clients (like the one we will be developing in part II of this series).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Our focus of this series is on &lt;strong&gt;extensibility.&lt;/strong&gt; I do have some ideas for&amp;nbsp;future posts on TFS customization, so make sure you subscribe to our RSS feed!&lt;/p&gt; &lt;h3&gt;The Team Foundation Core Services&lt;/h3&gt; &lt;p&gt;The Team Foundation Core Services (&lt;font face="Courier New" size="2"&gt;TFCS&lt;/font&gt;) are a set of services running on the Application Tier of TFS, which allow us to access the different aspects of Team Foundation Server, including administration, security and events. &lt;font face="Courier New" size="2"&gt;TFCS&lt;/font&gt; enable customers and Microsoft Partners to extend Team Foundation functionality by developing Team System extensions and adapters to integrate third-party tools with Team System.&lt;/p&gt; &lt;p&gt;TFCS is made up our of five services:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Classification Service&lt;/strong&gt;. This service provides access to Team Project information, and the different structures that make up a Team Project.&amp;nbsp;In this article, we will mainly be focusing on this service.  &lt;li&gt;&lt;strong&gt;Eventing Service&lt;/strong&gt;. The Eventing Service allows Team Foundation Servers to communicate by raising events and listening for events. This is how tools like &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET" target="_blank"&gt;CruiseControl.Net&lt;/a&gt; are able to kick of a build in response to a check in. They use the Eventing Service to listen for these events, and react appropriately. We will use the Eventing service in our custom WCF client, to keep our displayed information synchronized with the TFS repository at all times. &lt;li&gt;&lt;strong&gt;Linking Service&lt;/strong&gt;. This service provides the ability to link items together, such as Work Items and files that are version controlled. One interesting aspect of the Linking Service is that you can create a link between two artifacts that were created by different tools which have no knowledge of each other. This type of loose coupling is achieved by assigning Uri to each artifact in the TFS repository, and creating links between these Uri's. &lt;li&gt;&lt;strong&gt;Registration Service&lt;/strong&gt;. The Registration Service allows a TFS component to discover other services registered on Team Foundation Server. Therefore, when you create a new TFS service, it should be registered on the service by using the Registration Service, so that it can be found and utilized by the other server components. You&amp;nbsp;can compare the Registration Service to a UDDI registry for Web Services. &lt;li&gt;&lt;strong&gt;Security Service&lt;/strong&gt;. The security service implements a unified security model used by Team Foundation Server to manage users, groups and permissions. If you create a custom TFS component, you have the ability to integrate your extension into this security model, and have your artifacts behave correctly within the TFS security model.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The above services are implemented as Web Services. Team Explorer and the different components of Team Foundation use the above services to implement their functionality. As I mentioned before, you will not often have a reason to call these web services directly. Instead, you will use&amp;nbsp; the &lt;strong&gt;Team Foundation Object Model&lt;/strong&gt; to interact with these Core Services. This is what we will do to implement our Console, WCF and PowerShell clients.&lt;/p&gt; &lt;p&gt;An overview diagram is shown below:&lt;/p&gt; &lt;p&gt;&lt;a title="TFSObjectModelOverview" href="http://www.flickr.com/photos/99548241@N00/1810347928/"&gt;&lt;img alt="TFSObjectModelOverview" src="http://static.flickr.com/2142/1810347928_b2d74b88af.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In the next sections, we will take a more detailed look at the Classification Service. Future articles will take a look at the other services within the context of the overall article.&lt;/p&gt; &lt;h3&gt;The Classification Service&lt;/h3&gt; &lt;p&gt;&amp;nbsp;The classification service provides access to Team Project information, including the Team Project name and the Uri, as well as access to the areas and iterations of the project. The Area and Iterations sections of a Team Project form the structure of the project. This service allows you to view project information, and make changes to a project's structure. An example of using this service would be to populate the top nodes of a tree view that looks like the main tree view of team explorer, showing the names of all of the Team Projects on the server. From these nodes you could then use other services to create the other nodes in the tree (such as accessing the Work Items that belong to a Team Project, which is what we will be doing in our custom WCF client).&lt;/p&gt; &lt;p&gt;Some example of the services offered up by the Classification Servers are listed below:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Creating a new Team Project.  &lt;li&gt;Delete an existing Team Project.  &lt;li&gt;Access the&amp;nbsp;properties (name, Uri, process template Id and Project properties) of the Team Project.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The common pattern for accessing the object model is to first establish a connection to the server Once you have a connection to the server, you can query the server for the type of interface you would like to use. This model is not unlike the WF Runtime Model, where you can ask the Workflow Runtime for the different services, such as the persistence or threading service.&lt;/p&gt; &lt;p&gt;To access the Classificiation service, you query the server for the &lt;font face="Courier New" size="2"&gt;ICommonStructureService&lt;/font&gt; type, defined in the &lt;font face="Courier New" size="2"&gt;Microsoft.TeamFoundation.Server&lt;/font&gt; namespace in the &lt;font face="Courier New" size="2"&gt;Microsoft.TeamFoundation.Server.dll&lt;/font&gt; assembly.&lt;/p&gt; &lt;p&gt;In my next post, we will dive head-first into the Classification service, and the &lt;font face="Courier New" size="2"&gt;TeamFoundationServer&lt;/font&gt; object, which is at the root of the Team Foundation Object Model hierarchy.&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:b6ea5f5c-152c-4afb-a6c7-698327731c22" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Team%20Foundation%20Server" rel="tag"&gt;Team Foundation Server&lt;/a&gt;, &lt;a href="http://technorati.com/tags/TFS" rel="tag"&gt;TFS&lt;/a&gt;, &lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Team%20Explorer" rel="tag"&gt;Team Explorer&lt;/a&gt;, &lt;a href="http://technorati.com/tags/TeamPrise" rel="tag"&gt;TeamPrise&lt;/a&gt;&lt;/div&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=209" width="1" height="1"&gt;</content><author><name>bennie</name><uri>http://footheory.com/members/bennie.aspx</uri></author></entry><entry><title>Code for"Writing Custom Cmdlets for Windows PowerShell" now available in the Downloads Section</title><link rel="alternate" type="text/html" href="http://footheory.com/blogs/bennie/archive/2007/10/07/code-for-writing-custom-cmdlets-for-windowns-powershell-now-available-in-the-downloads-section.aspx" /><id>http://footheory.com/blogs/bennie/archive/2007/10/07/code-for-writing-custom-cmdlets-for-windowns-powershell-now-available-in-the-downloads-section.aspx</id><published>2007-10-08T00:43:39Z</published><updated>2007-10-08T00:43:39Z</updated><content type="html">&lt;p&gt;The code for the article &lt;a href="http://footheory.com/blogs/bennie/archive/2007/09/24/writing-custom-cmdlets-for-windows-powershell.aspx" target="_blank"&gt;Writing Custom Cmdlets for Windows PowerShell&lt;/a&gt; is now available in the &lt;a href="http://footheory.com/files/folders/powershell/entry192.aspx" target="_blank"&gt;download&lt;/a&gt; section. The sample includes the code for the cmdlet itself, the unit tests, and a&amp;nbsp; class library with a sample pipeline input object.&lt;/p&gt; &lt;p&gt;Any feedback on either the article or the code is greatly appreciated!&lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=193" width="1" height="1"&gt;</content><author><name>bennie</name><uri>http://footheory.com/members/bennie.aspx</uri></author></entry><entry><title>Wr