<?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 : Design Pattern</title><link>http://blogs.msdn.com/johnwpowell/archive/tags/Design+Pattern/default.aspx</link><description>Tags: Design Pattern</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>Implementing the "Only Talk to Friends" pattern using the InternalsVisibleTo Attribute</title><link>http://blogs.msdn.com/johnwpowell/archive/2008/05/09/implementing-the-only-talk-to-friends-pattern-using-the-internalsvisibleto-attribute.aspx</link><pubDate>Fri, 09 May 2008 15:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8479744</guid><dc:creator>johnwpowell</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/johnwpowell/comments/8479744.aspx</comments><wfw:commentRss>http://blogs.msdn.com/johnwpowell/commentrss.aspx?PostID=8479744</wfw:commentRss><description>&lt;P mce_keep="true"&gt;Did your parents ever tell you "don't talk to strangers?"&amp;nbsp; They were trying to protect you, and even though you are all grown up now, that principle is still relevant--to the design of your software, that is.&amp;nbsp; The basic idea is that classes should limit their surface area and not expose that which reveals implementation details.&amp;nbsp; Let's go though an example to illustrate these concepts.&lt;/P&gt;
&lt;P mce_keep="true"&gt;In a traditional layered architecture you logically divide components by responsibility.&amp;nbsp; In this example, we will use a domain, business and data access logic layer each realized as a Visual Studio 2008 project.&amp;nbsp; In our contrived architecture, we want the business layer to be the "gatekeeper" for retrieving customer domain objects.&amp;nbsp; The business layer uses the data access logic layer to fetch a customer, so we &lt;EM&gt;might&lt;/EM&gt; expose the data access class as a property of the business class as demonstrated here:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersIteration1_4.png" mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersIteration1_4.png"&gt;&lt;IMG height=238 alt=DontTalkToStrangersIteration1 src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersIteration1_thumb_1.png" width=648 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersIteration1_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;Here's the code to use this design:&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersCodeIteration1_4.png" mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersCodeIteration1_4.png"&gt;&lt;IMG height=44 alt=DontTalkToStrangersCodeIteration1 src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersCodeIteration1_thumb_1.png" width=557 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersCodeIteration1_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;So what's wrong with this approach?&amp;nbsp; We have violated a core principal of object oriented design by exposing implementation details.&amp;nbsp; Just like your parents protected you from strangers, classes should not expose their children or any other details about implementation.&amp;nbsp; You may have heard of this concept by another name such as:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Don't Talk to Strangers&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Principal of Least Knowledge&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Demeter's Law&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;Consumers don't need to know how the CustomerBusiness fetches a Customer, it only needs to know that CustomerBusiness fetches a customer.&amp;nbsp; So, let's revise the design using a technique called &lt;STRONG&gt;interface promotion&lt;/STRONG&gt;.&amp;nbsp; This involves hiding a child object and promoting all or some of its interface to the parent.&amp;nbsp; The new design looks like this:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersIteration2_2.png" mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersIteration2_2.png"&gt;&lt;IMG height=233 alt=DontTalkToStrangersIteration2 src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersIteration2_thumb.png" width=642 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersIteration2_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;Here's the code to use the new design:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersCodeIteration2_2.png" mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersCodeIteration2_2.png"&gt;&lt;IMG height=38 alt=DontTalkToStrangersCodeIteration2 src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersCodeIteration2_thumb.png" width=480 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/DontTalkToStrangersCodeIteration2_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H3&gt;Only Talk to Friends&lt;/H3&gt;
&lt;P mce_keep="true"&gt;The responsibility of the business layer is to act as a "gatekeeper" and control access to the underlying layers.&amp;nbsp; Although it might seem that we have accomplished our goal with this design, there is another issue that needs to be addressed.&amp;nbsp; Remember the layered architecture?&amp;nbsp; Business logic is in one project/assembly and data access logic is in another.&amp;nbsp; In order for CustomerBusiness to use CustomerData, the methods in CustomerData must be public.&amp;nbsp; The implication of this is &lt;STRONG&gt;a consumer can reference the data access layer and call it's public methods, bypassing any logic in the business layer&lt;/STRONG&gt;.&amp;nbsp; To solve this problem, I would like to introduce a technique that I call &lt;STRONG&gt;only talk to friends&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;The intent of the only talk to friends pattern is provide a mechanism for an assembly to expose it's interface to specified friend assemblies.&amp;nbsp; In our example, the data access logic layer would only expose it's interface to the business layer.&amp;nbsp; In order to accomplish this, let's revisit the design and make the CustomerData class and its methods internal:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/CustomerData_2.png" mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/CustomerData_2.png"&gt;&lt;IMG height=131 alt=CustomerData src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/CustomerData_thumb.png" width=425 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/CustomerData_thumb.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Now for the magic. Add the InternalsVisibleTo attribute to the AssemblyInfo.cs file in the Data project thereby exposing anything internal in the data access logic layer to the business layer.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/image_2.png"&gt;&lt;IMG height=33 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/image_thumb.png" width=354 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/image_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;The InternalsVisibleTo attribute exposes anything internal in one assembly to the specified friend assembly.&amp;nbsp; It would be nice if we could be more granular than the entire assembly, but this approach will work well for most circumstances.&lt;/P&gt;
&lt;H3&gt;Sometimes It's OK to Talk to Strangers&lt;/H3&gt;
&lt;P mce_keep="true"&gt;There is one exception for breaking the "do not talk to strangers" principle, and that is unit testing.&amp;nbsp; When we write the unit test for CustomerBusiness, we only want to test CustomerBusiness, not CustomerData or the database.&amp;nbsp; In order to do this, we mock the CustomerData class.&amp;nbsp; For this work, CustomerBusiness will need to provide a mechanism that allows the unit test to replace the CustomerData instance in CustomerBusiness.&amp;nbsp; There are a few techniques for doing this such as dependency injection (and I do have an article planned on this subject), but one way is to allow CustomerData to be passed into the CustomerBusiness constructor as follows.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/image_6.png" mce_href="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/image_6.png"&gt;&lt;IMG height=329 alt=image src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/image_thumb_2.png" width=475 border=0 mce_src="http://blogs.msdn.com/blogfiles/johnwpowell/WindowsLiveWriter/ImplementingTheOnlyTalktoFriendsPatternU_10C77/image_thumb_2.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;Note that &lt;STRONG&gt;the constructor that allows the data access object to be specified is internal&lt;/STRONG&gt;.&amp;nbsp; Once again, you use the InternalsVisibleTo attribute granting access only to the business layer unit tests.&lt;/P&gt;
&lt;H3&gt;Summary&lt;/H3&gt;
&lt;P mce_keep="true"&gt;I hope this article has reinforced the object-oriented principle "don't talk to strangers," and provided a modern spin, "only talk to friends," that you can add to your toolbox.&lt;/P&gt;
&lt;H3&gt;References&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.amazon.com/exec/obidos/tg/detail/-/0131489062/qid=1102729726/sr=8-1/ref=sr_8_xs_ap_i1_xgl14/102-5016397-2387360?v=glance&amp;amp;s=books&amp;amp;n=507846" target=_blank mce_href="http://www.amazon.com/exec/obidos/tg/detail/-/0131489062/qid=1102729726/sr=8-1/ref=sr_8_xs_ap_i1_xgl14/102-5016397-2387360?v=glance&amp;amp;s=books&amp;amp;n=507846"&gt;Applying UML and Patterns&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://www.cmcrossroads.com/bradapp/docs/demeter-intro.html" target=_blank mce_href="http://www.cmcrossroads.com/bradapp/docs/demeter-intro.html"&gt;Introducing Demeter and Its Laws&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://en.wikipedia.org/wiki/Law_of_Demeter" mce_href="http://en.wikipedia.org/wiki/Law_of_Demeter"&gt;Law of Demeter&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx"&gt;InternalsVisibleTo Attribute Class&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8479744" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/johnwpowell/archive/tags/InternalsVisibleTo/default.aspx">InternalsVisibleTo</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/Don_2700_t+Talk+to+Strangers/default.aspx">Don't Talk to Strangers</category></item></channel></rss>