<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>John W Powell : WCF</title><link>http://blogs.msdn.com/johnwpowell/archive/tags/WCF/default.aspx</link><description>Tags: WCF</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Consume SharePoint Web Services with WCF using the Repository, Gateway, Mapper, Domain Model and Factory Design Patterns</title><link>http://blogs.msdn.com/johnwpowell/archive/2009/01/03/consume-sharepoint-web-services-with-wcf-using-the-repository-gateway-mapper-domain-model-and-factory-design-patterns.aspx</link><pubDate>Sun, 04 Jan 2009 00:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9270662</guid><dc:creator>johnwpowell</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/johnwpowell/comments/9270662.aspx</comments><wfw:commentRss>http://blogs.msdn.com/johnwpowell/commentrss.aspx?PostID=9270662</wfw:commentRss><description>&lt;P&gt;The SharePoint developer community has produced a wealth of knowledge and code samples that demonstrate how to consume SharePoint web services and leverage them in domain-specific applications.&amp;nbsp; This information is often task-centric, such as&amp;nbsp; "How to add an Item to a List using SharePoint Web Services."&amp;nbsp;&amp;nbsp; In this article, we will take a framework-centric approach and apply sound, fundamental object-oriented (OO) design principles to implement a reusable library for working with the SharePoint web services. &lt;/P&gt;
&lt;H3&gt;Motivation and Goals&lt;/H3&gt;
&lt;P&gt;My motivation for this article is to help you create a foundation for a framework that can be used in one, or reused across many SharePoint-integrated applications.&amp;nbsp; I also want to demonstrate how good software design principles can (and should) be applied to SharePoint development, and confess my own sins for not always following them.&amp;nbsp; For some reason, I often find myself thinking procedurally when developing a SharePoint customization.&amp;nbsp; Perhaps it's because the product is a 70% solution and requires a different mindset and approach than a large greenfield software project does.&amp;nbsp; Maybe customers expect results faster when you build it on SharePoint, and I've taken shortcuts to meet them.&amp;nbsp; Or maybe I've just been lazy, but in any case, here are some of the issues I've seen or been responsible for:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Re-writing the same SharePoint code on each new project 
&lt;LI&gt;Not refactoring within and across applications 
&lt;LI&gt;Tightly coupling application code to the XML input and output from SharePoint services 
&lt;LI&gt;Lack of a domain model; designing procedurally instead of applying domain-driven design (DDD) 
&lt;LI&gt;Not having well-defined layers and strategies 
&lt;LI&gt;Failure to design for testability and not writing unit tests&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Here are some of the goals I would like to achieve with this framework:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Implement a domain model that is independent and decoupled from the SharePoint services 
&lt;LI&gt;Define a set of patterns and strategies for communicating with the SharePoint services 
&lt;LI&gt;Create a reusable library that can be used in many different domain-specific applications 
&lt;LI&gt;Use DDD and Test-Driven-Design (TDD) 
&lt;LI&gt;Apply good OO principals and patterns 
&lt;LI&gt;Use Windows Communication Foundation (WCF)&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Design&lt;/H3&gt;
&lt;P&gt;In the next section, I'll walk through the implementation and the process I went through to arrive at the design below.&amp;nbsp; Generally speaking, I used DDD and TDD (where it made sense) and followed the Single Responsibility principle.&amp;nbsp; If you are not familiar with this, it is often described as "a class should only have one reason to change."&amp;nbsp; I call it the "&lt;EM&gt;and&lt;/EM&gt; test."&amp;nbsp; I describe the purpose of the class and if I have to use the word &lt;EM&gt;and&lt;/EM&gt;, I consider refactoring some of the functionality to another class.&lt;/P&gt;
&lt;P&gt;In the diagram below, the client application uses the &lt;EM&gt;repository&lt;/EM&gt; and &lt;EM&gt;domain&lt;/EM&gt; classes.&amp;nbsp; The repository is responsible for retrieving domain objects based on criteria.&amp;nbsp; The repository uses one or more &lt;EM&gt;service gateways&lt;/EM&gt; to get the information it needs.&amp;nbsp; The service gateway communicates with the SharePoint web services using a WCF client.&amp;nbsp; The service calls typically return XML responses, and it is the job of the &lt;EM&gt;service response mapper&lt;/EM&gt; to translate the XML to a domain object.&amp;nbsp; Finally, the WCF client factory creates clients configured to call the SharePoint services.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://dmfyxa.blu.livefilestore.com/y1p-jNcgP6Mi2JH-RjylslbXH9lLohguNO84QYKIvH9IP0LvoRQWsD8WXagNh0BD6Jn9YrEzS_8nT0CkvxtsaCMTg/SharePointSamples.Patterns.zip?download" target=_blank mce_href="http://dmfyxa.blu.livefilestore.com/y1p-jNcgP6Mi2JH-RjylslbXH9lLohguNO84QYKIvH9IP0LvoRQWsD8WXagNh0BD6Jn9YrEzS_8nT0CkvxtsaCMTg/SharePointSamples.Patterns.zip?download"&gt;Get the code&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/SPServicePattern_2.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/SPServicePattern_2.png"&gt;&lt;IMG height=164 alt=SPServicePattern src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/SPServicePattern_thumb.png" width=616 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/SPServicePattern_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Implementation&lt;/H3&gt;
&lt;P&gt;In this example, the goal is to get all the lists in a given site.&amp;nbsp; Following DDD, we will start the design in the domain layer and create a list class that has a title property:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_2.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_2.png"&gt;&lt;IMG height=196 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb.png" width=440 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Create the list repository class to define the method clients will call the get the lists in a given site:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_8.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_8.png"&gt;&lt;IMG height=258 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_3.png" width=600 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_3.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Following TDD, we'll create a unit test that will fail until we implement the repository:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_22.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_22.png"&gt;&lt;IMG height=262 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_9.png" width=394 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_9.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Return to the repository class and add the implementation to call the lists service gateway which we haven't created yet.&amp;nbsp; How did I know to create a lists service gateway?&amp;nbsp; I decided to have a gateway that corresponds to each SharePoint web service and did some research to find the exact service and method that would return the lists for a given site.&amp;nbsp; The implementation below is very simple, but you can imagine a more complex repository that uses several service gateways and does some additional processing to construct a domain object graph.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_20.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_20.png"&gt;&lt;IMG height=264 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_8.png" width=571 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_8.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Create the lists service gateway so the project will compile:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_10.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_10.png"&gt;&lt;IMG height=275 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_4.png" width=606 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_4.png"&gt;&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Create a failing unit test for the lists service gateway:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_18.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_18.png"&gt;&lt;IMG height=384 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_1.png" width=634 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_1.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Next we'll add a reference to the SharePoint Lists service.&amp;nbsp;&amp;nbsp; Note: Visual Studio will add an app.config and a Properties &amp;gt; DataSources folder and you can delete both of them.&amp;nbsp; We are going to configure WCF programmatically.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_16.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_16.png"&gt;&lt;IMG height=436 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_7.png" width=535 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_7.png"&gt;&lt;/A&gt;&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Return to the lists service gateway and fill in the implementation.&amp;nbsp; Now I'm pulling a "Julia Childs" on you.&amp;nbsp; I already went through several iterations of TDD and refactoring to arrive at the implementation below.&amp;nbsp; Initially this method had all the code to call the web service, and there was no WCF client factory nor a mapper.&amp;nbsp; After implementing this logic in several gateways, I refactored the commonality to classes.&amp;nbsp; It made sense to have a factory to construct WCF clients in a consistent way and allow me to make a change in one place if I discovered something new.&amp;nbsp; The Single Responsibility "&lt;EM&gt;and&lt;/EM&gt; test" led me to refactor the mapping code to a separate class and the end result is a much cleaner implementation:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_24.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_24.png"&gt;&lt;IMG height=327 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_10.png" width=621 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_10.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Next, we'll implement the WCF client factory.&amp;nbsp; As you can see, it has been through a few iterations of TDD and refactoring starting with the service url class.&amp;nbsp; This class contains constants and methods for working with SharePoint service urls.&amp;nbsp; The other thing you'll notice is the the WCF configuration that is typically done in a configuration file is being done programmatically in the service binding factory class.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_26.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_26.png"&gt;&lt;IMG height=381 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_11.png" width=835 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_11.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Here is the implementation of the service binding factory:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_28.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_28.png"&gt;&lt;IMG height=280 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_12.png" width=749 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_12.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The gateway uses a mapper to map the XML response from the SharePoint web service to a domain object.&amp;nbsp; The XML response is in the form of &amp;lt;element attribute1...n /&amp;gt; which, in this case, translates nicely to domain objects and properties.&amp;nbsp; The code below uses Linq to find all List elements and for each one it calls MapInternal which creates a list object from the element:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_30.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_30.png"&gt;&lt;IMG height=551 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_13.png" width=649 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_13.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now if we return to the repository GetLists unit test, it passes and output each list title in the site:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_32.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_32.png"&gt;&lt;IMG height=270 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_14.png" width=402 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ConsumeSharePointWebServiceswithWCFusing_D2A4/image_thumb_14.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Summary&lt;/H3&gt;
&lt;P&gt;In this article and walkthrough, I demonstrated how DDD, TDD, patterns and good OO principles can be applied to implement a framework that consumes SharePoint web services.&amp;nbsp; Even though I focused on the web services, the SharePoint API can also be regarded as a service and the same fundamentals can be applied to developing applications that run on the server.&amp;nbsp; I hope this inspires and helps you to implement your own framework and improve the quality and reuse of your SharePoint code.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://dmfyxa.blu.livefilestore.com/y1p-jNcgP6Mi2JH-RjylslbXH9lLohguNO84QYKIvH9IP0LvoRQWsD8WXagNh0BD6Jn9YrEzS_8nT0CkvxtsaCMTg/SharePointSamples.Patterns.zip?download" target=_blank mce_href="http://dmfyxa.blu.livefilestore.com/y1p-jNcgP6Mi2JH-RjylslbXH9lLohguNO84QYKIvH9IP0LvoRQWsD8WXagNh0BD6Jn9YrEzS_8nT0CkvxtsaCMTg/SharePointSamples.Patterns.zip?download"&gt;Get the code&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;References and Additional Reading&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://martinfowler.com/eaaCatalog/" target=_blank mce_href="http://martinfowler.com/eaaCatalog/"&gt;Catalog of Patterns of Enterprise Application Architecture&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://www.amazon.com/Enterprise-Application-Architecture-Addison-Wesley-Signature/dp/0321127420/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1231018800&amp;amp;sr=8-1" target=_blank mce_href="http://www.amazon.com/Enterprise-Application-Architecture-Addison-Wesley-Signature/dp/0321127420/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1231018800&amp;amp;sr=8-1"&gt;Patterns of Enterprise Application Architecture&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/magazine/cc546578.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/magazine/cc546578.aspx"&gt;Patterns in Practice: The Open Closed Principle&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9270662" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/Pattern/default.aspx">Pattern</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/Design+Pattern/default.aspx">Design Pattern</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/TDD/default.aspx">TDD</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/SharePoint+2007/default.aspx">SharePoint 2007</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/DDD/default.aspx">DDD</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/SharePoint+Web+Services/default.aspx">SharePoint Web Services</category></item><item><title>Build PowerShell CmdLets to call SharePoint Web Services using WCF</title><link>http://blogs.msdn.com/johnwpowell/archive/2008/11/02/build-powershell-cmdlets-to-call-sharepoint-web-services-using-wcf.aspx</link><pubDate>Mon, 03 Nov 2008 00:22:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9029678</guid><dc:creator>johnwpowell</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/johnwpowell/comments/9029678.aspx</comments><wfw:commentRss>http://blogs.msdn.com/johnwpowell/commentrss.aspx?PostID=9029678</wfw:commentRss><description>&lt;P&gt;In this post I'll show you how to build a PowerShell cmdlet that consumes SharePoint web services using WCF.&amp;nbsp; What I like about this approach is that it provides the ability to use &lt;EM&gt;some&lt;/EM&gt; of the SharePoint API without having to be logged in to the SharePoint server.&amp;nbsp; Although you can accomplish the same thing using PowerShell scripts and functions, in this post we'll build a SharePoint cmdlet using C#.&amp;nbsp; &lt;/P&gt;
&lt;H3&gt;About the Approach&lt;/H3&gt;
&lt;P&gt;There are several advantages of combining PowerShell and SharePoint web services:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Consume the SharePoint API without logging on to a SharePoint server 
&lt;LI&gt;Provide a layer of abstraction and reusable task-oriented building blocks 
&lt;LI&gt;Reduce risk of performance issues caused by PowerShell scripts that don't dispose of unmanaged SharePoint resources&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;There are also some drawbacks to writing custom cmdlets that consume SharePoint web services:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;SharePoint web services do not expose the full API; you may need to augment them with business-specific functionality 
&lt;LI&gt;Cmdlets require compilation and additional overhead over script file&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Getting Started&lt;/H3&gt;
&lt;P&gt;In this walkthrough, I'm using Visual Studio 2008 on a SharePoint virtual machine.&amp;nbsp; Although you &lt;EM&gt;could&lt;/EM&gt; use a Visual Studio PowerShell project template, we'll are going to build everything by hand so there are no mysteries.&amp;nbsp; So let's get started by creating a new class library project:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_2.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_2.png"&gt;&lt;IMG height=163 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb.png" width=240 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb.png"&gt;&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Add a reference to PowerShell which is contained in System.Management.Automation assembly.&amp;nbsp; If you've installed the Windows SDK, you can find it in the following location: C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image3.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image3.png"&gt;&lt;IMG height=197 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image3_thumb.png" width=240 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image3_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Since we are creating a class that will both describe and install a custom snap in, we need to reference System.Configuration.Install&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image9.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image9.png"&gt;&lt;IMG height=197 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image9_thumb.png" width=240 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image9_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H3&gt;Create the Snap In and Cmdlet&lt;/H3&gt;
&lt;P&gt;Add a new class that inherits CustomPSSnapIn.&amp;nbsp; Add the RunInstaller attribute to the class and describe the snap in by overriding the Name, Vendor and Description properties.&amp;nbsp; Your code should end up looking like this:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image12.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image12.png"&gt;&lt;IMG height=783 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image12_thumb.png" width=515 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image12_thumb.png"&gt;&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Add a new class that inherits from Cmdlet.&amp;nbsp; We'll build a cmdlet to get information about a SharePoint site, so name it "GetSPWebCmdlet."&amp;nbsp; Add the Cmdlet attribute to the class. You'll notice the cmdlet name, "Get-SPWeb" is a combination of the noun string &lt;EM&gt;SPWeb&lt;/EM&gt; and verb enumeration &lt;EM&gt;VerbsCommon.Get&lt;/EM&gt; specified by the Cmdlet attribute:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image18.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image18.png"&gt;&lt;IMG height=289 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image18_thumb.png" width=386 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image18_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Override the Cmdlets property in the snap in class and add the Get-SPWeb cmdlet to the Cmdlets collection:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image21.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image21.png"&gt;&lt;IMG height=231 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image21_thumb.png" width=805 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image21_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H3&gt;Configure Visual Studio to Install and Add the Snap In When the Project is Debugged&lt;/H3&gt;
&lt;P&gt;Before we add any code to the cmdlet, let's configure Visual Studio to automatically deploy the snap in to make debugging easier.&amp;nbsp; We'll use a post-build event to install the snap in, so in the spirit of learning PowerShell, we'll write the post-build script in PowerShell!&amp;nbsp; Add a new text file to your project named PostBuildEvent.ps1.&amp;nbsp; Add the following script to the file:&lt;/P&gt;
&lt;P&gt;trap &lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; $errorTxt = $_.Exception.Message&lt;BR&gt;&amp;nbsp;&amp;nbsp; write-output "$errorTxt"&lt;BR&gt;&amp;nbsp;&amp;nbsp; break&lt;BR&gt;} 
&lt;P&gt;$targetDir = $args[0]&lt;BR&gt;$targetFileName = $args[1]&lt;BR&gt;$snapInName = $args[2] 
&lt;P&gt;write-output "Deploying..."&lt;BR&gt;join-path $targetDir $targetFileName&lt;BR&gt;write-output "Snap In Name: $snapInName" 
&lt;P&gt;set-location $targetDir&lt;BR&gt;set-alias installutil $env:windir\Microsoft.NET\Framework\v2.0.50727\installutil&lt;BR&gt;installutil $targetFileName 
&lt;P&gt;Notice the script file takes some arguments (targetDir, targetFileName and snapInName).&amp;nbsp; Using that information, it installs the SnapIn (and our SharePoint cmdlet).&amp;nbsp; Configure Visual Studio to pass the arguments to the post-build event:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image27.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image27.png"&gt;&lt;IMG height=235 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image27_thumb.png" width=422 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image27_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;After a SnapIn is installed, you have to add it to your environment before it can be used.&amp;nbsp; As you can see, even though our custom snap in has been installed, it is not listed when you call &lt;EM&gt;Get-PSSnapin&lt;/EM&gt;:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_20.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_20.png"&gt;&lt;IMG height=212 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_7.png" width=640 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_7.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;To add it, call &lt;EM&gt;Add-PSSnapin&lt;/EM&gt; passing in the name of the assembly:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_22.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_22.png"&gt;&lt;IMG height=158 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_9.png" width=640 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_9.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;We don't want to add the snap in after each code change, so we are going to automate it by adding a console file that will add the snap in into our environment when the project is debugged.&amp;nbsp; Add a new file named SharePointSamples.Console.psc1 to your project.&amp;nbsp; Put the following xml in the file:&lt;/P&gt;
&lt;P&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;BR&gt;&amp;lt;PSConsoleFile ConsoleSchemaVersion="1.0"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;PSVersion&amp;gt;1.0&amp;lt;/PSVersion&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;PSSnapIns&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;PSSnapIn Name="SharePointSamples.PowerShell" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/PSSnapIns&amp;gt;&lt;BR&gt;&amp;lt;/PSConsoleFile&amp;gt; 
&lt;P&gt;In the project configuration, Debug settings, configure Visual Studio to start PowerShell when you debug and in the command-line arguments section, use the -PSConsoleFile argument to specify the console file you created:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_16.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_16.png"&gt;&lt;IMG height=316 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_2.png" width=499 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_2.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H3&gt;Implement the Cmdlet&lt;/H3&gt;
&lt;P&gt;Now that deployment and debugging are taken care of, add the following code to the cmdlet:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_24.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_24.png"&gt;&lt;IMG height=568 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_10.png" width=711 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_10.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The cmdlet takes the url of the site as an argument.&amp;nbsp; Arguments are implemented as class properties decorated with the &lt;EM&gt;Parameter&lt;/EM&gt; attribute.&amp;nbsp; The work is implemented in the &lt;EM&gt;ProcessRecord&lt;/EM&gt; method.&amp;nbsp; As you can see, I already did some re-factoring and created a service locator class that will give me an instance of the SharePoint &lt;EM&gt;Webs&lt;/EM&gt; service (using WCF).&amp;nbsp; The code then invokes the &lt;EM&gt;GetWeb&lt;/EM&gt; method and writes out the resulting xml.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Here is the code for the service locator.&amp;nbsp; As you can see it configures the SharePoint Webs proxy: &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_28.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_28.png"&gt;&lt;IMG height=324 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_12.png" width=640 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_12.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Most of the key WCF configuration settings for integrated authentication are implemented in the BindingFactory class:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_30.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_30.png"&gt;&lt;IMG height=311 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_13.png" width=640 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_13.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;H3&gt;Test the Cmdlet&lt;/H3&gt;
&lt;P&gt;To test the cmdlet, run the project.&amp;nbsp; When the PowerShell command prompt opens, type &lt;EM&gt;Get-SPWeb&lt;/EM&gt;.&amp;nbsp; You will be prompted for the site url if you don't provide it:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_26.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_26.png"&gt;&lt;IMG height=217 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_11.png" width=505 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/d480dd7087aa_8548/image_thumb_11.png"&gt;&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Summary&lt;/H3&gt;
&lt;P&gt;In this walkthrough, you learned how to leverage PowerShell, WCF and the SharePoint web services to implement a custom cmdlet.&amp;nbsp; Using this approach, you can expand the administrative capabilities of SharePoint and build reusable, task-oriented building blocks to increase your productivity and capability.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://cid-7cedcb8ed3a44629.skydrive.live.com/self.aspx/Public/SharePointSamples.zip" target=_blank mce_href="http://cid-7cedcb8ed3a44629.skydrive.live.com/self.aspx/Public/SharePointSamples.zip"&gt;Get the code&lt;/A&gt; for this article.&lt;/P&gt;
&lt;H3&gt;Additional Reading&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.capdes.com/2007/03/visual_studio_post_build_event.html" target=_blank mce_href="http://www.capdes.com/2007/03/visual_studio_post_build_event.html"&gt;Visual Studio Build Events With PowerShell&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://www.wrox.com/WileyCDA/Section/id-320555.html" target=_blank mce_href="http://www.wrox.com/WileyCDA/Section/id-320555.html"&gt;Extending Windows Powershell with Snap-ins&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://sharepoint.microsoft.com/blogs/zach/Lists/Posts/Post.aspx?List=90bbfd11-c9a5-45cf-a77e-19559aae81ae&amp;amp;ID=7" target=_blank mce_href="http://sharepoint.microsoft.com/blogs/zach/Lists/Posts/Post.aspx?List=90bbfd11-c9a5-45cf-a77e-19559aae81ae&amp;amp;ID=7"&gt;Managing SharePoint with PowerShell&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://cglessner.blogspot.com/2008/06/powershell-sharepoint.html" target=_blank mce_href="http://cglessner.blogspot.com/2008/06/powershell-sharepoint.html"&gt;PowerShell &amp;amp; SharePoint - Quick Start&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://darrinbishop.com/blog/archive/2007/04/08/54.aspx" target=_blank mce_href="http://darrinbishop.com/blog/archive/2007/04/08/54.aspx"&gt;SharePoint and PowerShell Demo&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://www.trentswanson.com/post/2008/01/Calling-SharePoint-web-services-using-Visual-Studio-20082c-WCF2c-and-Windows-Auth.aspx" target=_blank mce_href="http://www.trentswanson.com/post/2008/01/Calling-SharePoint-web-services-using-Visual-Studio-20082c-WCF2c-and-Windows-Auth.aspx"&gt;Calling SharePoint web services using Visual Studio 2008, WCF, and Windows Authentication&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://darrinbishop.com/blog/archive/2007/11/28/psfivefunctions.aspx" target=_blank mce_href="http://darrinbishop.com/blog/archive/2007/11/28/psfivefunctions.aspx"&gt;Five Simple But Powerful PowerShell Functions/Filters for SharePoint&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9029678" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/Windows+SharePoint+Services/default.aspx">Windows SharePoint Services</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/SharePoint+2007/default.aspx">SharePoint 2007</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/PowerShell/default.aspx">PowerShell</category></item><item><title>How to Create a Reusable WCF Service Host for Windows Services and Self-Hosting</title><link>http://blogs.msdn.com/johnwpowell/archive/2008/09/20/how-to-create-a-reusable-wcf-service-host-for-windows-services-and-self-hosting.aspx</link><pubDate>Sat, 20 Sep 2008 23:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8960197</guid><dc:creator>johnwpowell</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/johnwpowell/comments/8960197.aspx</comments><wfw:commentRss>http://blogs.msdn.com/johnwpowell/commentrss.aspx?PostID=8960197</wfw:commentRss><description>&lt;P&gt;In this article, I'll show you how to create a reusable service host that can be run from either from the console (self-hosted) or installed as a Windows service.&amp;nbsp; I'll also demonstrate how to use a configuration file instead of code to control which WCF services the host starts.&amp;nbsp; Finally, I'll show how you can make the Windows service installer flexible to allow you to run multiple versions of the service on the same machine.&amp;nbsp; Before getting into implementation details, I'd like to share my motivations behind this solution.&lt;/P&gt;
&lt;H3&gt;Why I Developed This Solution&lt;/H3&gt;
&lt;P&gt;If you have been doing WCF development, you have probably experienced some pain around service hosting.&amp;nbsp; Some of the things I found frustrating on my first WCF project included:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Making a decision on the type of service host 
&lt;LI&gt;Discovering it's more work to host as a Windows service than IIS! 
&lt;LI&gt;Installing, starting, stopping and uninstalling a service during development 
&lt;LI&gt;Re-writing the same Windows service plumbing for each WCF service 
&lt;LI&gt;Having to change code if I wanted to add or remove the WCF services that are hosted 
&lt;LI&gt;Trying to host multiple versions of a service on the same machine&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Having learned a few things, but by no means an expert, I decided to implement a more flexible and reusable service host to meet these goals:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Create a single Windows service project that can be shared by all WCF services in the solution 
&lt;LI&gt;Keep the service project separate from the service host project 
&lt;LI&gt;Ability to run the service host from the console or a Windows service 
&lt;LI&gt;Ability to test the service host during development without having to install it 
&lt;LI&gt;Ability to host multiple versions of a service on the same machine in production 
&lt;LI&gt;Ability to control which WCF services are hosted without having to make code changes&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;How it Works&lt;/H3&gt;
&lt;P&gt;Now that you understand the &lt;EM&gt;why&lt;/EM&gt;, I'll show you &lt;EM&gt;how&lt;/EM&gt; the service host works starting with the entry point: Main().&amp;nbsp; The output type of a Windows service project is an executable.&amp;nbsp; When the service starts, it calls the executable.&amp;nbsp; Here is the default Main method for a Windows service project:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_4.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_4.png"&gt;&lt;IMG height=259 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_1.png" width=409 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;As you can see this code creates an instance of the service and runs it.&amp;nbsp; To execute this code, you have to install the service and start it.&amp;nbsp; Although it seems like you could run the executable from the command line, you will receive the following error if you try:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_8.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_8.png"&gt;&lt;IMG height=197 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_3.png" width=489 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_3.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;So to get around this, we are going to send an argument to the executable that switches it between a Windows service and self-hosting.&amp;nbsp; During development, we can configure Visual Studio to pass the command line argument to test the code.&amp;nbsp; In production, this same mechanism can provide additional diagnostic capabilities.&amp;nbsp; Here is the new implementation of Main():&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_6.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_6.png"&gt;&lt;IMG height=582 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_2.png" width=602 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_2.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H3&gt;Running the Service Host from the Command Line&lt;/H3&gt;
&lt;P&gt;When run from the command line using the self-hosting argument, the service host starts the WCF services and outputs information to the console:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_10.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_10.png"&gt;&lt;IMG height=357 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_4.png" width=741 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_4.png"&gt;&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Running the Service Host as a Windows Service&lt;/H3&gt;
&lt;P&gt;To run the service host as a Windows service, you first must install it.&amp;nbsp; To do this, copy the output of the service host project to a directory on the server.&amp;nbsp; If there are two versions of the service to run, you'd copy the output to different folders (you also need to configure the services to have different endpoints in the configuration file).&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_14.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_14.png"&gt;&lt;IMG height=223 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_6.png" width=555 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_6.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;To install the service, run installutil on the service host executable, passing different parameters for the name and displayname, for example:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;cd C:\Windows\Microsoft.NET\Framework64\v2.0.50727 &lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;installutil /name=CalcV1 /displayname="Calc V1" /description="Sample Calculator Service" "c:\CalcV1\WcfSample.Service.Host.exe"&lt;BR&gt;installutil /name=CalcV2 /displayname="Calc V2" /description="Sample Calculator Service" "c:\CalcV2\WcfSample.Service.Host.exe"&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;After installing, you will see the services in Windows:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_12.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_12.png"&gt;&lt;IMG height=44 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_5.png" width=578 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_5.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;To update the WCF service, stop the Windows service, copy the new WCF service dll and restart the Windows service.&amp;nbsp; There shouldn't be a need to update the service host executable.&amp;nbsp; To uninstall the service, use the /u argument, for example:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;installutil /u /name=CalcV1 "c:\CalcV1\WcfSample.Service.Host.exe"&lt;BR&gt;installutil /u /name=CalcV2 "c:\CalcV2\WcfSample.Service.Host.exe"&lt;/EM&gt;&lt;/P&gt;
&lt;H3&gt;Using the Same Service Host for Multiple WCF Services&lt;/H3&gt;
&lt;P&gt;In the previous section, you saw parameters passed into the service installer (note the forward slash parameter name format such as /name).&amp;nbsp; In the service host project, there is an installer component.&amp;nbsp; In that component, you can access the parameters through the Context object.&amp;nbsp; So instead of hard-coding the service name, we set the service name from the parameters.&amp;nbsp; That's all there is to it.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_20.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_20.png"&gt;&lt;IMG height=247 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_9.png" width=631 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_9.png"&gt;&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Controlling Which WCF Services are Hosting Using a Configuration File&lt;/H3&gt;
&lt;P&gt;Now, let's examine how to control which WCF services are hosted using a configuration file.&amp;nbsp; I was initially planning to iterate the service elements in the system.serviceModel section and start all services.&amp;nbsp; You can see an example in this &lt;A href="http://www.topxml.com/rbnews/WSCF/WCF/re-42352_Start-ServiceHosts-for-all-configured-Services.aspx" target=_blank mce_href="http://www.topxml.com/rbnews/WSCF/WCF/re-42352_Start-ServiceHosts-for-all-configured-Services.aspx"&gt;post&lt;/A&gt; and this &lt;A href="http://blogs.thinktecture.com/ingo/archive/2006/09/05/414686.aspx" target=_blank mce_href="http://blogs.thinktecture.com/ingo/archive/2006/09/05/414686.aspx"&gt;post&lt;/A&gt;.&amp;nbsp; I found two problems with this approach.&amp;nbsp; First, you can't control which services to start--like if I wanted to have the configuration for five WCF services, but only start one.&amp;nbsp; Second, the service name element doesn't allow you to specify an assembly name, just the namespace and class.&amp;nbsp; I need the assembly name to load the WCF service type at runtime.&amp;nbsp; To overcome both of these problems, I created a configuration section that allows you to specify which services to start.&amp;nbsp; Here is a sample configuration showing this:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_16.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_16.png"&gt;&lt;IMG height=355 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_7.png" width=640 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_7.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The service container class gets the custom configuration section and iterates through the services list and starts each one:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_18.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_18.png"&gt;&lt;IMG height=434 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_8.png" width=1077 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_8.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H3&gt;Separating the WCF Service from the Service Host&lt;/H3&gt;
&lt;P&gt;One of the goals I had for this solution was to separate concerns by keeping the WCF service separate from the service host.&amp;nbsp; In the example below, you can see how the Calculator service is in a separate project than the Host.&amp;nbsp; The only coupling between these two projects is necessary.&amp;nbsp; The Host project has a project reference to the WCF service project so we can load the service assembly at runtime.&amp;nbsp; In this example, there is only one service project, but you can imagine a separate project for each type of service.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_22.png" target=_blank mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_22.png"&gt;&lt;IMG height=350 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_10.png" width=285 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/HowtoCreateaWCFServiceHostforHostingServ_C4C0/image_thumb_10.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;H3&gt;Conclusion and Link to Download the Code&lt;/H3&gt;
&lt;P&gt;This article presented an approach for creating a reusable WCF service host that enables you to specify which WCF services to run using configuration and support hosting multiple versions of a service on the same machine.&amp;nbsp; Hopefully, the techniques presented here improve your WCF service development and deployment experience.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://cid-7cedcb8ed3a44629.skydrive.live.com/self.aspx/Public/WcfSampleServiceHost.zip" target=_blank mce_href="http://cid-7cedcb8ed3a44629.skydrive.live.com/self.aspx/Public/WcfSampleServiceHost.zip"&gt;Get the Code&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8960197" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/WCF/default.aspx">WCF</category></item></channel></rss>