<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>The Inquisitive Coder - Davy Brion&#039;s Blog &#187; WCF</title> <atom:link href="http://davybrion.com/blog/category/wcf/feed/" rel="self" type="application/rss+xml" /><link>http://davybrion.com/blog</link> <description>inquisitive: adjective. given to inquiry, research, or asking questions; eager for knowledge; intellectually curious</description> <lastBuildDate>Sun, 29 Jan 2012 10:48:12 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Why You Shouldn&#8217;t Expose Your Entities Through Your Services</title><link>http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/</link> <comments>http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/#comments</comments> <pubDate>Mon, 17 May 2010 15:18:43 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Architecture]]></category> <category><![CDATA[Code Quality]]></category> <category><![CDATA[Opinions]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2318</guid> <description><![CDATA[I sometimes still get questions from people who want to expose their entities through their WCF Services.&#160; Regardless of whether these are entities that are populated through NHibernate or any other ORM, this is just not a good thing to do.&#160; Many people prefer to accept and return entities through their services because they believe [...]]]></description> <content:encoded><![CDATA[<p>I sometimes still get questions from people who want to expose their entities through their WCF Services.&#160; Regardless of whether these are entities that are populated through NHibernate or any other ORM, this is just not a good thing to do.&#160; Many people prefer to accept and return entities through their services because they believe this is an easier programming model.&#160; They believe that it takes less work than mapping to DTO’s and that as a whole, this solution is much more manageable.&#160; Rest assured that this is a fallacy.&#160; Any perceived benefit that you’ll get from exposing entities outside of your service layer will only last a <em>very short time</em> and will quickly be dwarfed by added complexity, increased maintenance overhead and a performance overhead which must not be ignored.&#160;</p><p>In this post, i’d like to take the chance to explain the downsides to exposing entities through services.&#160; Though i’ll probably miss quite a few of the downsides (feel free to add to the list through comments), the ones i will mention are IMO important enough to take note of.</p><p><strong>Exposing entities to clients means your clients are very tightly coupled to your service(s)</strong></p><p>Entities are a part of your domain.&#160; These entities in your domain can change for various reasons.&#160; Sometimes because functional changes are required, but quite often also for optimizations (whether they are for performance reasons or to improve the clarity and maintainability of your domain).&#160; Functional changes <em>can </em>impact your clients, though that is not necessarily the case.&#160; Optimizations hardly ever have an impact on your clients (other than possibly improved response times from your service calls obviously).&#160; If your service layer accepts and returns domain entities, each possible change is highly likely to have an impact on your clients.&#160; And this impact is not cheap.&#160; In the best case scenario, it means updating your service contracts, regenerating your service proxies and redeploying your clients.&#160; In the worst case scenario, it means making actual changes to the code of your clients.&#160; And for what? Because of changes that shouldn’t have impacted your clients in the first place?</p><p>Ideally, your clients are as dumb as they can be.&#160; They should know as little as possible about the actual <em>implementation</em> of the domain because that implementation is simply not relevant to them.&#160; They should present users with data and give them the option to modify that data, to trigger actions and to perform certain tasks.&#160; They should focus squarely on those tasks and pretty much everything else is typically better suited to be done behind your service layer.&#160; If you build your clients with no real knowledge of the actual domain model, but of DTO’s and possible actions to be performed then you can reduce the level of coupling between your clients and your services substantially.</p><p>Many of the people who prefer to expose entities often claim that going for the DTO approach introduces too much extra work and too many extra, seemingly unnecessary classes.&#160; For starters, they don’t want to write code that maps entities to DTO’s.&#160; First of all, the amount of code that this requires is in reality <em>very small</em>, not to mention <em>very easy</em>.&#160; Secondly, you can just as well use a library such as AutoMapper to take that pain away from you.&#160; And contrary to what you might think, there is a big performance gain to be had from returning DTO’s over entities, but i’ll get to that in the next section.</p><h5></h5><h5></h5><p><strong>Entities are hardly ever the most optimal representation of data</strong></p><p>I think we can safely say that most applications need to show data in the following 3 ways:</p><ul><li>In a grid view, either as a total listing of all instances of a certain type of data or the result of a search query or some kind of filtering action</li><li>In dropdown controls or anything else that lets users select pieces of data</li><li>In edit screens where a piece of data needs to be displayed in its entirety, perhaps even to be modified by the user</li></ul><p>There are undoubtedly more ways in which data can be presented to the user but i think it’s safe to say that most business applications will certainly rely on the following 3 ways quite heavily.</p><p>In the case of a grid view, you’re frequently showing data that is related to more than one entity.&#160; You’ll often need to include the name or the description of some associated entities.&#160; So what exactly is it that you want to do in this situation?&#160; Do you want to return a list of the main entities of the grid view, which all have their required association properties filled in so you can display the columns that you need in the grid view?&#160; Do you actually need all of the properties of these entities (for both the main entities and the associated entities)?&#160; Odds are high that you’re going to be returning a lot more data to the client than you actually need.&#160; And that is what is realistically going to hurt the performance of your system.&#160; Any piece of unnecessary data that you transmit to your clients has a cost associated with it.&#160; The unnecessary data is retrieved from the database.&#160; The entities are then serialized at the service end.&#160; Then they are transmitted to the client.&#160; Then they are deserialized by your client.&#160; All of this is pretty costly, so the more unnecessary data that is included in this operation, the more your performance and the responsiveness of your client (not to mention your database and your server) is impacted negatively.</p><p>In the case of dropdown controls or anything else that lets users select pieces of data, you typically only need very few of the properties of that piece of data.&#160; In many cases, the primary key and a name or a description are sufficient.&#160; Do you really need to transmit the entire entity every time for usages like this? Again, keep in mind that all of that extra data that will never be used by your client needs to be retrieved, serialized, transmitted and deserialized again.&#160; Surely, this is an awful waste, no?&#160;</p><p>And then there’s the case where a piece of data needs to be displayed in its entirety.&#160; In these cases, you will almost always need all of the properties of the entity that is displayed, but you’ll most often also need to show other data (things that can be selected, or linked to the main entity).&#160; This other data will in most cases fall into the previous category where you’ll only need very little information about the actual entity.&#160; If you’re smart, you’ve chosen the DTO approach to retrieve this data for the data that can be selected, and in that case, you already have all of the infrastructural code in place to project entities or data into DTO’s.&#160; So you might as well reuse it for the main entity as well since you already have the capability to do this.</p><p>Always keep in mind that your entities will frequently either contain <em>more data than needed</em>, or <em>less data than needed</em>.&#160; As such, it just doesn’t make much sense to expose entities to your clients since they are hardly ever optimal for client-side usage.&#160; If you really want to think about performance, stop worrying about the supposed cost of mapping to DTO’s (which is truly negligible) and start focusing on <em>what</em> your actually <em>sending</em> to and from your service because this is far more costly than any kind of DTO-mapping really is.</p><p><strong>Must your data really come from entities?</strong></p><p>If you are displaying data to your user, does that data really need to come from your domain model?&#160; Does it really need to be retrieved by populating a collection of entities to then return them to the client?&#160; Again, keep the <em>form</em> of the data in mind when thinking about this.&#160; In many cases, as i mentioned above, an entity is not the most optimal form of the data that your client needs.&#160; So why even retrieve it through entities? Sure, asking your ORM to retrieve a set of entities based on a set of criteria is often the easiest thing to do, but if the easiest path were the best path, the overall quality of software projects wouldn’t be in the sad state that it’s in today.&#160; If the form of the required data is not identical to the structure of an entity, it’s often far more optimal to simply populate a DTO <em>directly from the data.</em>&#160; With NHibernate, you can easily do this by adding a list of projections to your query and then using a ResultTransformer to populate the DTO’s based on the direct output of the query.&#160; In this case, no entity instance ever needs to be created when you’re just retrieving data, and no extra mapping between the entity and the DTO’s needs to be performed.&#160; Your data access code simply retrieves the resulting data from a query, and puts that data directly in your DTO’s.&#160; There’s no reason why usage of an ORM should prevent you from doing this.&#160;&#160; Once again, this approach will offer far more performance benefits than avoiding DTO mapping at all costs ever can.</p><p><strong>What about the behavior of your entities?</strong></p><p>Do your entities have any behavior in them?&#160; If not, they are already more of a DTO than a true entity.&#160; In fact, if your entities have no behavior at all, you could even wonder why you’re using an ORM in the first place.&#160; Now, behavior can mean many things.&#160; It could mean lazy loading of associations.&#160; It could mean actual business logic.&#160; Obviously, lazy-loading doesn’t (and shouldn’t!) work client-side, but what about your business logic? Do you have business logic that <em>can </em>be executed client-side? Or is it business logic that should only be executed behind the service layer? If so, how do you make the distinction between this to prevent client-side usage from these entities? Whatever you do, you’re pretty much opening up a can of worms that really is better avoided in the first place.</p><p><strong>How are you going to deal with technical issues?</strong></p><p>Accepting and returning entities from services introduces a host of technical issues that can be quite substantial.&#160; Serialization and deserialization specifically are issues that you need to be worried about.&#160; If you’re using an ORM which does lazy-loading of associations, this will certainly cause serialization issues that you need to work around.&#160; You can either disable lazy loading, or you can make sure that your entities are always fully initialized (as in: always have their associations fully loaded) before they are sent back to the client.&#160; Disabling lazy-loading <em>will </em>cause performance problems in your service layer, either in places where you don’t expect them to be or in places that you haven’t thought of before it’s too late.&#160; Fully loading your entities and their associates before returning them is another performance nightmare waiting to happen so that’s really not an ideal solution either.&#160; You can try to hook into the serialization process or even the lazy-loading features of your ORM but whatever you do in that case will be a hack that <em>will</em> cause issues sooner or later.&#160; And again, all of these problems can very easily be avoided with a solution which, i hope you realize by now, offers plenty more benefits than any solution where you accept/return entities in your service.</p><p><strong>Conclusion</strong></p><p>Every single downside to exposing entities through services are issues that i have myself encountered in past projects, either ones i’ve worked on myself, or ones that i’ve seen other people work on.&#160; If that’s not enough for you, then maybe you’ll find it interesting to know that some of the brightest and most respected people (like Udi Dahan and Ayende for instance) in the .NET community also actively recommend against exposing entities through services because of the same downsides that i mentioned, though they could probably give you even more downsides that i forgot to cover in this post.&#160; These downsides are not figments of anyone’s imagination.&#160; They are very real, and you really, really ought to think twice before dismissing this advice.&#160;</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F05%2Fwhy-you-shouldnt-expose-your-entities-through-your-services%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/"  data-text="Why You Shouldn&rsquo;t Expose Your Entities Through Your Services" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/feed/</wfw:commentRss> <slash:comments>26</slash:comments> </item> <item><title>Clients Shouldn&#8217;t Define Your Services</title><link>http://davybrion.com/blog/2010/04/clients-shouldnt-define-your-services/</link> <comments>http://davybrion.com/blog/2010/04/clients-shouldnt-define-your-services/#comments</comments> <pubDate>Mon, 05 Apr 2010 16:35:53 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2010/04/clients-shouldnt-define-your-services/</guid> <description><![CDATA[I just got a question about an earlier post of mine, in which i describe how i use NHibernate in my WCF services.&#160; Here’s the question that i got: My architecture at works requires a web app and a windows app to talk to the application server via WCF. The Application server being where all [...]]]></description> <content:encoded><![CDATA[<p>I just got a question about an earlier post of mine, in which i describe <a
href="http://davybrion.com/blog/2009/12/using-nhibernate-in-your-service-layer" target="_blank">how i use NHibernate in my WCF services</a>.&#160; Here’s the question that i got:</p><blockquote><p>My architecture at works requires a web app and a windows app to talk to the application server via WCF. The Application server being where all the Data access and Service libraries live. I intend to implement NHibernate into the project. But wanted to get some pointers if your approach above is recommended for Web and Windows clients alike when sending and receiving data via WCF?</p></blockquote><p>The short answer to that question is simply: It sure as hell is!</p><p>But you know i always prefer the longer answer <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .&#160; The type of client always has an impact on the usage patterns of the service(s) that it needs.&#160; A web client will often have a different usage pattern than a windows client or a mobile client will.&#160; Each client should be able to consume the service in the manner that is most suitable to its requirements and constraints.&#160; A web client is (or should be) completely stateless so a service that is meant to be used by a web client is typically geared towards that stateless model.&#160;&#160; Windows clients or mobile clients are typically not entirely stateless and as such, the way they could use a service in the most optimal way often differs from how a web client would use the service.</p><p>One of the most important SOA principles is that there should be no implicit coupling between a service and its client(s) at all.&#160; Generally speaking, coarse-grained operations are favored over fine-grained ones due to the cost of the communication overhead.&#160; Yet, that easily conflicts with the usage patterns of different clients.&#160; Since a web client is stateless, it often needs more coarse grained operations than a windows client which can retain data in its own process memory and thus, might benefit more from calling a fine-grained operation here and there.</p><p>Obviously, my solution to that problem is <a
href="http://code.google.com/p/agatha-rrsl/" target="_blank">Agatha</a> which makes it possible to implement each operation (or call them actions or commands and queries or whatever else you can think of) in the way that just makes the most sense, no matter what kind of client is going to call them.&#160; Each client can consume the service operations in a manner that is optimal to the client, without the typical design impact and overhead that you have with traditional WCF services.</p><p>We have a few services that serve multiple types of clients.&#160; ASP.NET pages.&#160; Silverlight applications. Windows Services.&#160; WPF tools.&#160; Outlook add-ins.&#160; And guess what?&#160; Those services don’t have a clue as to who or what is using them and they are all implemented in the same way.&#160; And it hasn’t caused a single problem or difficult design decision (as to the service API) yet.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F04%2Fclients-shouldnt-define-your-services%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/04/clients-shouldnt-define-your-services/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/04/clients-shouldnt-define-your-services/"  data-text="Clients Shouldn&rsquo;t Define Your Services" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/04/clients-shouldnt-define-your-services/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/04/clients-shouldnt-define-your-services/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/04/clients-shouldnt-define-your-services/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Hey Microsoft, Our Databases Aren&#8217;t Services!</title><link>http://davybrion.com/blog/2010/01/hey-microsoft-our-databases-arent-services/</link> <comments>http://davybrion.com/blog/2010/01/hey-microsoft-our-databases-arent-services/#comments</comments> <pubDate>Sun, 17 Jan 2010 17:46:11 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Architecture]]></category> <category><![CDATA[Opinions]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2010/01/hey-microsoft-our-databases-arent-services/</guid> <description><![CDATA[Something that frequently bothers me is when people/companies create services that are basically thin layers on top of their database.&#160; The service contracts expose the typical CRUD operations for each table, and add some additional methods for specific queries etc.&#160; These kind of services will sometimes pretend to contain a bit of ‘business logic’ but [...]]]></description> <content:encoded><![CDATA[<p>Something that frequently bothers me is when people/companies create services that are basically thin layers on top of their database.&#160; The service contracts expose the typical CRUD operations for each table, and add some additional methods for specific queries etc.&#160; These kind of services will sometimes pretend to contain a bit of ‘business logic’ but they are essentially just a remote interface into your database with maybe a bit of extra security on top of it.&#160; They effectively turn your database into a remote service.&#160; Now if you’re anything like me, you’re probably thinking “why on earth would people do that?”</p><p>There are probably a few answers to that question, but one reason that can’t really be disputed is that a lot of the tooling that Microsoft offers to developers simply encourage this kind of stuff.&#160; Let’s go over a little example.</p><p>I wanted to see what some of Microsoft’s recommended tools would create for me if i wanted to create a Silverlight application which uses a database.&#160; Obviously, a Silverlight application can’t use a database directly so the application will need to communicate with a service.&#160; The service obviously does have access to the database.&#160; RIA Services is a solution that Microsoft seems to be pushing a lot for this specific scenario so i figured i’d give this a shot.</p><p>I created a RIA Services Class Library project in my solution and tried to add a ‘Domain Service Class’ (as the RIA Services templates call it) to the project.&#160; If you already have a DataContext or an ObjectContext defined within the same assembly, you can immediately select the database tables that you want to expose.&#160;&#160; So i canceled the dialog and quickly added an ADO.NET Entity Data Model to the solution for which i selected my <a
href="http://www.codeplex.com/ChinookDatabase" target="_blank">Chinook</a> database.&#160; I tried to create a ‘Domain Service Class’ again and got the following window:</p><p><a
href="http://davybrion.com/pictures/YourDatabaseIsNotAService_E97E/create_service.png" rel="prettyPhoto[2209]"><img
style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="create_service" border="0" alt="create_service" src="http://davybrion.com/pictures/YourDatabaseIsNotAService_E97E/create_service_thumb.png" width="454" height="554" /></a></p><p>Well, now that sure is easy isn’t it? I can immediately select all my ‘Entities’ and i can even check whether i want to be able to edit them through the service, and apparently i can also generate associated classes for metadata (which would be useful for validation according to the tooltip).&#160; I checked the Album table, and left the ‘Enable editing’ option unchecked.&#160; This created a service with the following code:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: green">// Implements application logic using the ChinookEntities context.</span></p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: green">// TODO: Add your application logic to these methods or in additional methods.</span></p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: green">// TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access</span></p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: green">// Also consider adding roles to restrict access as appropriate.</span></p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: green">// [RequiresAuthentication]</span></p><p
style="margin: 0px">&#160;&#160;&#160; [<span
style="color: #2b91af">EnableClientAccess</span>()]</p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">AlbumService</span> : <span
style="color: #2b91af">LinqToEntitiesDomainService</span>&lt;<span
style="color: #2b91af">ChinookEntities</span>&gt;</p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: green">// TODO: Consider</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: green">// 1. Adding parameters to this method and constraining returned results, and/or</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: green">// 2. Adding query methods taking different parameters.</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: #2b91af">IQueryable</span>&lt;<span
style="color: #2b91af">Album</span>&gt; GetAlbum()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> <span
style="color: blue">this</span>.ObjectContext.Album;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>I don’t know about you, but i love those TODO statements.&#160; After all, you really do might want to <em>consider</em> constraining the resultset that could be returned by the GetAlbum method.&#160;&#160; Who knows, perhaps you have certain use cases where you don’t want <em>all</em> of the ‘entities’ in the Album <em>table</em> to be returned by your ‘domain service’<em>.</em>&#160; Hopefully, this service will be used by developers who are smart enough to realize that they should modify this method, instead of using client-side LINQ statements to filter the returned Album ‘entities’ as i’m sure we’ve all seen in too many Microsoft demo’s already.</p><p>It gets better if you recreate the service and check the ‘Enable editing’ option.&#160; Now you’re ‘domain service’ will also contain the following methods:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> InsertAlbum(<span
style="color: #2b91af">Album</span> album)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.ObjectContext.AddToAlbum(album);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> UpdateAlbum(<span
style="color: #2b91af">Album</span> currentAlbum)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> ((currentAlbum.EntityState == <span
style="color: #2b91af">EntityState</span>.Detached))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.ObjectContext.AttachAsModified(currentAlbum, <span
style="color: blue">this</span>.ChangeSet.GetOriginal(currentAlbum));</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> DeleteAlbum(<span
style="color: #2b91af">Album</span> album)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> ((album.EntityState == <span
style="color: #2b91af">EntityState</span>.Detached))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.ObjectContext.Attach(album);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.ObjectContext.DeleteObject(album);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Man, this sure is easy, isn’t it? I now have a service that offers me full CRUD access to the Album table in my database.&#160; If i wanted to, i could now start implementing a screen in my Silverlight application which allows my users to list the albums, edit them, delete them, create new ones, etc… and i wouldn’t even have to change anything in my ‘service layer’.&#160;&#160; The problem is that too many developers actually will do exactly that.&#160;&#160; After all, why should they doubt any code that was generated by a tool which comes from Microsoft?&#160; If the tool can generate this, then certainly some people actually want you to use it like this, no?&#160; If not, why would it even generate code like this?</p><p>I’m sure this kind of stuff gets a lot of ooh’s and aah’s during the product demo’s at Microsoft events, but other than that, what good does this really bring?&#160; Is this really the way you want people to develop their services?&#160; Do you really want developers to pretty much expose the database as-is to remote clients?&#160; And those TODO statements simply won’t cut it, you know that all too well.&#160; I simply don’t think there’s any good reason to generate code like this because a lot of people will simply take it as is and use it like that directly from their client code.&#160; Oh sure, most of them will hook up the authentication but i’m willing to bet that very few people will actually put real business logic in there.&#160; Why would they?&#160; The message that a lot of people will get from the resulting code is that a service is merely a way to provide CRUD for your database tables.&#160; What’s business logic to these people?&#160; Right, the stuff they’ll implement in their presentation layer because this service doesn’t really encourage people to consider implementing it there.</p><p>The <em>only </em>benefit that i can see from using RIA services is that you don’t really have to deal with your service contracts, and your operation contracts or any of that stuff.&#160;&#160; No, we won’t be doing any of that.&#160; We simply use a [EnableClientAccess] attribute and we’re done!&#160; I don’t really consider that a benefit, though i can certainly understand why people would not want to deal with <a
href="http://davybrion.com/blog/2009/07/why-i-dislike-classic-or-typical-wcf-usage/" target="_blank">the pain of classic WCF services</a>.&#160; RIA Services is simply a solution to the <em>wrong</em> problem.</p><p>I haven’t looked at ADO.NET Data Services (which will be renamed to WCF Data Services in .NET 4.0) yet, but i suppose it’ll be more of the same: something that makes it incredibly easy to create services directly on top of your database data.</p><p>Seriously though: who on earth actually <em>wants </em>that?</p><p>I have no doubt that there are some people out there that are using RIA Services in a responsible manner and are sticking by responsible architectural guidelines.&#160; I also have no doubt that those people are ignoring most of the tooling that is offered by Microsoft around it.&#160; So really, why not get rid of this kind of tooling, and spend the effort that normally goes into those tools (or anything else which encourages bad practices for that matter) on providing actual guidance to the developers of your platform?&#160; The last thing we need are more developers who think that this is ‘ok’, or projects that have been delivered based on this kind of ‘architecture’, or customers that are turned off by .NET projects because “they all have maintenance problems”.&#160;</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F01%2Fhey-microsoft-our-databases-arent-services%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/01/hey-microsoft-our-databases-arent-services/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/01/hey-microsoft-our-databases-arent-services/"  data-text="Hey Microsoft, Our Databases Aren&rsquo;t Services!" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/01/hey-microsoft-our-databases-arent-services/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/01/hey-microsoft-our-databases-arent-services/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/01/hey-microsoft-our-databases-arent-services/feed/</wfw:commentRss> <slash:comments>29</slash:comments> </item> <item><title>Integrated Security With Silverlight And WCF</title><link>http://davybrion.com/blog/2009/11/integrated-security-with-silverlight-and-wcf/</link> <comments>http://davybrion.com/blog/2009/11/integrated-security-with-silverlight-and-wcf/#comments</comments> <pubDate>Tue, 03 Nov 2009 11:41:32 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Silverlight]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1856</guid> <description><![CDATA[I lost some time yesterday trying to get a Silverlight client to use Integrated Security with a WCF service so i figured i'd post the steps necessary to make it work here. First of all, you need to make sure that your IIS installation has support for Windows Authentication. Go to Add/Remove Programs (appwiz.cpl), click [...]]]></description> <content:encoded><![CDATA[<p>I lost some time yesterday trying to get a Silverlight client to use Integrated Security with a WCF service so i figured i'd post the steps necessary to make it work here.</p><p>First of all, you need to make sure that your IIS installation has support for Windows Authentication.  Go to Add/Remove Programs (appwiz.cpl), click on Turn Windows Features on or off, select Internet Information Services - World Wide Web Services - Security and make sure that Windows Authentication is checked.</p><p>Next, you need to make sure that the virtual directory where you're hosting the WCF service has Windows Authentication enabled.  Open Internet Information Services Manager (inetmgr), select the virtual directory where the WCF service is hosted, click on the Authentication icon and enable Windows Authentication.</p><p>After that, you need to add the following to the binding configuration of the service endpoint (in the host, obviously):</p><div><pre class="brush: xml; title: ; notranslate">
          &lt;security mode=&quot;TransportCredentialOnly&quot;&gt;
            &lt;transport clientCredentialType=&quot;Windows&quot; /&gt;
          &lt;/security&gt;
</pre></div><p>I only got it working with basicHttpBinding, so unfortunately i can no longer use the customBinding to use binary XML...</p><p>In your Silverlight project, open the ServiceReferences.ClientConfig file and add the following to the binding configuration:</p><div><pre class="brush: xml; title: ; notranslate">
          &lt;security mode=&quot;TransportCredentialOnly&quot; /&gt;
</pre></div><p>After that, you should be able to do this in your WCF service:</p><div><pre class="brush: csharp; title: ; notranslate">
            WindowsIdentity myuser = ServiceSecurityContext.Current.WindowsIdentity;
</pre></div><p>And that should return the Windows user of the user running the Silverlight client.</p><p>For the record: this is with Silverlight 3... i have no idea if it'll work with Silverlight 2</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F11%2Fintegrated-security-with-silverlight-and-wcf%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/11/integrated-security-with-silverlight-and-wcf/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/11/integrated-security-with-silverlight-and-wcf/"  data-text="Integrated Security With Silverlight And WCF" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/11/integrated-security-with-silverlight-and-wcf/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/11/integrated-security-with-silverlight-and-wcf/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/11/integrated-security-with-silverlight-and-wcf/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Why I Dislike Classic Or Typical WCF Usage</title><link>http://davybrion.com/blog/2009/07/why-i-dislike-classic-or-typical-wcf-usage/</link> <comments>http://davybrion.com/blog/2009/07/why-i-dislike-classic-or-typical-wcf-usage/#comments</comments> <pubDate>Mon, 20 Jul 2009 22:54:40 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1453</guid> <description><![CDATA[If you've ever used or read about WCF, you've most likely seen classic or typical WCF usage. With that i mean service contracts with various operations on them, service implementations that either contain logic or always delegate to other classes, generated client proxies that need to be kept in synch every time you add an [...]]]></description> <content:encoded><![CDATA[<p>If you've ever used or read about WCF, you've most likely seen classic or typical WCF usage.  With that i mean service contracts with various operations on them, service implementations that either contain logic or always delegate to other classes, generated client proxies that need to be kept in synch every time you add an operation to a service and a lot of repetitive XML in your configuration files.  In some cases (usually for very specific services with limited functionality) there is nothing wrong with that.  But for a service layer that sits on top of your business layer so it can be used by the front end of your application (be it ASP.NET, Silverlight, a WPF client or whatever) i find typical WCF usage to be far from ideal.</p><p>My biggest issue with typical WCF usage is that of service contract design.  It's very hard to get this 'right' and most people simply don't.  First of all, you need to decide between fine-grained and coarse-grained operations.  Fine-grained operations typically lead to chatty communication between the client and the service, which could seriously impact performance and scalability.  Then again, fine-grained operations do offer a lot of flexibility when it comes to reusing functionality in various parts in the client.  Coarse-grained operations typically don't have the same negative effect on performance, but they can easily introduce implicit coupling between your service and the client which can get pretty annoying when you need to deal with a new kind of client, like a Silverlight application for instance (which tends to have different service usage patterns than typical ASP.NET applications).  It can also lead to duplication when parts of functionality offered by a coarse-grained operation are needed somewhere else.</p><p>Even if you do get the granularity of your operations right, you have to figure out where to put them.  Are you going to create a service for each kind of functional subdomain (billing, invoicing, registrations, etc...), for each entity that is 'known' to the client (there are many people who do this, unfortunately) or on a per-feature basis (story or use case driven)?  Every possible variation you can think of is already being used today, and they almost always come with a lot of disadvantages.  Get this part wrong and you can end up with clients that might need 2 or more service proxies just to show some related data on a screen (or worse, to complete a business transaction).  Whether you get it right or wrong, odds are high that you'll have spent quite a bit of time defining your service contracts.  Time that might have been better off being spent on other parts.</p><p>The second thing that bothers me a lot about typical WCF usage is the quality of the code in service implementations.  In the worst cases, these classes actually contain true business logic to implement the service operations.  That's not just breaking the Single Responsibility Principle, it's more like assaulting it.  Whether they contain actual business logic or merely delegate to other classes, these service implementations will need to talk to instances of classes or components that they depend on sooner or later.  My question is, where do these instances come from?  Do you manually resolve them through your IOC container?  Do you have them injected in your service instance (if creation of the service instance is controlled by an IOC container, that is)?  What if the granularity of the service contract forces the service implementation to depend on components that might not be used together in all operations?</p><p>And then there's the thorny issue of cross cutting concerns within service implementations.  How many times have you seen the same old tired logging and exception handling code repeated in every service operation? How about transaction handling, auditing, authorization or resource management? True, you can plug into WCF's extensibility model (if you're willing to look for it...) or use AOP tricks to minimize that kind of code duplication but that in turn limits your possibilities when you want to add just a little bit of custom code to some of the cross cutting concern's logic when needed.  In most cases, service implementations simply contain a lot of smelly code, the large majority of which is essentially a form of waste.</p><p>That's already an important list of problems when designing and implementing typical WCF services.  But what about using typical WCF services?  This is somewhat problematic as well, IMHO.  First of all, you'll need a proxy to access the service.  You can either develop these proxies yourself, or you can generate them through visual studio, svcutil, or custom tools that you (or others) developed.  Whatever way you choose to use, you can't escape the fact that you constantly have to keep those proxy implementations in synch with their respective service contract.  Every single time one of the developers adds an operation to a service (which is pretty often once there are a few people working on a large project), you're going to have to do something to make sure you can access that operation through your proxy.  It's usually not a lot of work, but it does kinda disrupt your coding flow.  Over and over again.  It can also be a pain in the ass when it comes to source control conflicts.</p><p>Then there's the actual matter of using the proxy instances.  Can you implement your story or use case with just one client proxy type? Great! Do you reuse the channel when making multiple service calls? You do? Great! Do you make sure you handle faulted channels properly?  And if you need multiple client proxy types (depending on your service contract granularity), are you aware of the fact that you are using multiple WCF channels (and yes, they are expensive) which are often kept open longer than they should be if you're not careful?  Are you generally careful about chatty communication? Obviously, that last one depends on the contract of the service and not really the implementation of the client proxy.  There are quite a lot of things you need to keep in mind when using these proxies.</p><p>My final thing on the list of 'dislikes' is the configuration that is required to use these services.  For every service you expose you'll need to add some XML to your configuration file.  Twice even (server <em>and</em> client)!  Most of this XML configuration is extremely tedious and very repetitive which just invites minor mistakes to be made.  Those minor mistakes could lead to a lot of debugging/problem solving time though.</p><p>I've been subjected to each and every one of the issues i've mentioned in projects that made typical use of WCF (or classic ASP.NET Web Services for that matter).  This type of service layer implementation is, IMHO, hurtful for productivity, detrimental to code quality and i don't really like the implicit trade-off between reusability and performance/scalability (depending on the granularity of your operations).</p><p>About a year ago, i really wanted to figure out a way to implement services which would enable me to keep fine-grained operations on my service layer without having to pay the performance/scalability penalty for that.  As some of you already know, that led to the whole WCF call batching thing (more info <a
href="http://davybrion.com/blog/2008/06/batching-wcf-calls/">here</a> and <a
href="http://davybrion.com/blog/2008/07/batching-wcf-calls-take-2/">here</a>) which i later on called the <a
href="http://davybrion.com/blog/2008/07/the-request-response-service-layer/">Request/Response Service Layer</a>.  Some people liked the approach, but i don't think anyone else actually uses it.  At least, i've never heard of anyone using it in a real project.</p><p>Well obviously, we've been using this at work for about a year now and while i won't claim that it's perfect (hint: nothing is), it has worked very well for us in several projects.  More specifically, this approach has offered us the following benefits, which heavily contrast all of the downsides of typical WCF usage that i listed above:</p><ul><li>Since we only have one service contract with one service operation, we don't need to spend time thinking about how to design and implement our service contracts and our operations.  After all, every operation that the service layer must support is a specific request type that can be added, together with its requesthandler.</li><li>We can keep our operations as fine-grained as we want (which increases reusability and overall flexibility), without having to pay the cost for chatty network communication by batching multiple requests per roundtrip as much as possible in a transparent manner.</li><li>The actual implementation of our service is very minimal.  It's just a small class which resolves the appropriate requesthandler through the IOC container, based on the type of the incoming request.  It then delegates to the requesthandler by passing the request to it, and it returns the response to the client.  We can simply add 'operations' by adding request types and requesthandlers to our assemblies... everything gets registered automatically when the application starts up</li><li>We avoid repetitive code for cross cutting concerns by putting it in a base requesthandler class that the other ones inherit from.  That kind of code now only occurs once, and we can plug in custom code at any point of the execution by simply using the <a
href="http://en.wikipedia.org/wiki/Template_method_pattern">Template Method pattern</a>.<li>The implementation of our requesthandlers doesn't contain any code that doesn't have to be there.  Each requesthandler simply implements the Handle method to handle the incoming request, and can do as it pleases to fulfill the request.  All dependencies are injected automatically by the IOC container.  It's usually nothing more than using the dependencies to execute the necessary business logic and then returning a response-derived object.</li><li>Since we only have one service, we only need one client proxy which never needs to be updated (technically, we have 2: one which is entirely asynch and mostly used in Silverlight clients, and one which is strictly synchronous and is mostly used by ASP.NET applications and Windows Services or command line tools.</li><li>This single client proxy implementation can make sure that underlying WCF resources are utilized as efficiently as possible and cleaned up properly throughout the client application(s).</li><li>The client proxy is easy to stub during unit tests which increases the testability of our client side code.</li><li>Very little configuration.  We only have to configure one client-side endpoint, and one server-side endpoint.  That's it.</li><li>All of this is very easy to put in some kind of reusable library.  Our applications simply reference the library, inherit from the base requesthandler types, make sure everything is registered properly upon application startup, add a couple of lines of XML and we can start the development of our service layer without any friction.</li></ul><p>The only downside to this approach that i can think of after using it for a year, is interoperability with other platforms.  I haven't used it in that situation yet, and while i do think it can be made to work i don't think it'll be easy nor pretty.</p><p>Now, just to be clear: this entire post was not a rant against WCF.  I actually do like WCF as a technology, it's just the typical usage patterns of WCF that i really dislike.  I love the fact that WCF is very extensible, configurable and flexible, but i merely consider it as a communication technology.  Nothing more, nothing less.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F07%2Fwhy-i-dislike-classic-or-typical-wcf-usage%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/07/why-i-dislike-classic-or-typical-wcf-usage/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/07/why-i-dislike-classic-or-typical-wcf-usage/"  data-text="Why I Dislike Classic Or Typical WCF Usage" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/07/why-i-dislike-classic-or-typical-wcf-usage/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/07/why-i-dislike-classic-or-typical-wcf-usage/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/07/why-i-dislike-classic-or-typical-wcf-usage/feed/</wfw:commentRss> <slash:comments>25</slash:comments> </item> <item><title>Calculating The Size Of SOAP Messages</title><link>http://davybrion.com/blog/2009/03/calculating-the-size-of-soap-messages/</link> <comments>http://davybrion.com/blog/2009/03/calculating-the-size-of-soap-messages/#comments</comments> <pubDate>Wed, 11 Mar 2009 11:06:34 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1104</guid> <description><![CDATA[I recently needed something to log the size of incoming and outgoing SOAP messages, and my first implementation of calculating the size looked like this: &#160;&#160;&#160; &#160;&#160;&#160; private static double GetMessageLengthInKB(Message message) &#160;&#160;&#160; &#160;&#160;&#160; { &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; return Math.Round(Encoding.UTF8.GetBytes(message.ToString()).Length / 1024d, 2); &#160;&#160;&#160; &#160;&#160;&#160; } There is a big problem with this. Well, at [...]]]></description> <content:encoded><![CDATA[<p>I <a
href="http://davybrion.com/blog/2009/03/i-love-easy-extensibility/">recently</a> needed something to log the size of incoming and outgoing SOAP messages, and my first implementation of calculating the size looked like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 9pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">double</span> GetMessageLengthInKB(<span
style="color: #2b91af;">Message</span> message)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: #2b91af;">Math</span>.Round(<span
style="color: #2b91af;">Encoding</span>.UTF8.GetBytes(message.ToString()).Length / 1024d, 2);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>There is a big problem with this.  Well, at least one that i know of, possibly more.  The ToString() method on the Message class returns the nicely formatted content of the message.  Including all whitespace.  This obviously increases the reported size of the SOAP message by a significant number, even though it's not sent over the wire with all that whitespace. A better way to calculate the size is like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 9pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">double</span> GetMessageLengthInKB(<span
style="color: #2b91af;">Message</span> message)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> writerSettings = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">XmlWriterSettings</span> { Encoding = <span
style="color: #2b91af;">Encoding</span>.UTF8, Indent = <span
style="color: blue;">false</span> };</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">using</span> (<span
style="color: blue;">var</span> memoryStream = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">MemoryStream</span>())</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">using</span> (<span
style="color: blue;">var</span> writer = <span
style="color: #2b91af;">XmlDictionaryWriter</span>.Create(memoryStream, writerSettings))</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; message.WriteMessage(writer);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.Flush();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: #2b91af;">Math</span>.Round(memoryStream.Position / 1024d, 2);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>One thing to keep in mind is that you need to be careful with writing the contents of a SOAP message.  If you write the content of a SOAP message without copying it first, you'll run into other problems further along the WCF pipeline.  So the MessageInspector now looks like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 9pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">MessageInspector</span> : <span
style="color: #2b91af;">IDispatchMessageInspector</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">readonly</span> <span
style="color: #2b91af;">ILog</span> logger = <span
style="color: #2b91af;">LogManager</span>.GetLogger(<span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">MessageInspector</span>));</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">object</span> AfterReceiveRequest(<span
style="color: blue;">ref</span> <span
style="color: #2b91af;">Message</span> request, <span
style="color: #2b91af;">IClientChannel</span> channel, <span
style="color: #2b91af;">InstanceContext</span> instanceContext)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (logger.IsInfoEnabled)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> bufferedCopy = request.CreateBufferedCopy(<span
style="color: blue;">int</span>.MaxValue);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> sizeLog = <span
style="color: blue;">string</span>.Format(<span
style="color: #a31515;">&quot;request message size: ~{0} KB&quot;</span>, GetMessageLengthInKB(bufferedCopy.CreateMessage()));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; logger.Info(sizeLog);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; request = bufferedCopy.CreateMessage();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">null</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> BeforeSendReply(<span
style="color: blue;">ref</span> <span
style="color: #2b91af;">Message</span> reply, <span
style="color: blue;">object</span> correlationState)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (logger.IsInfoEnabled)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> bufferedCopy = reply.CreateBufferedCopy(<span
style="color: blue;">int</span>.MaxValue);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> sizeLog = <span
style="color: blue;">string</span>.Format(<span
style="color: #a31515;">&quot;response message size: ~{0} KB&quot;</span>, GetMessageLengthInKB(bufferedCopy.CreateMessage()));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; logger.Info(sizeLog);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; reply = bufferedCopy.CreateMessage();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">double</span> GetMessageLengthInKB(<span
style="color: #2b91af;">Message</span> message)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> writerSettings = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">XmlWriterSettings</span> { Encoding = <span
style="color: #2b91af;">Encoding</span>.UTF8, Indent = <span
style="color: blue;">false</span> };</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">using</span> (<span
style="color: blue;">var</span> memoryStream = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">MemoryStream</span>())</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">using</span> (<span
style="color: blue;">var</span> writer = <span
style="color: #2b91af;">XmlDictionaryWriter</span>.Create(memoryStream, writerSettings))</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; message.WriteMessage(writer);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.Flush();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: #2b91af;">Math</span>.Round(memoryStream.Position / 1024d, 2);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>As you can see, you're better off creating a buffered copy of a message, and then creating a new message out of that copy before doing anything with it.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F03%2Fcalculating-the-size-of-soap-messages%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/03/calculating-the-size-of-soap-messages/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/03/calculating-the-size-of-soap-messages/"  data-text="Calculating The Size Of SOAP Messages" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/03/calculating-the-size-of-soap-messages/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/03/calculating-the-size-of-soap-messages/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/03/calculating-the-size-of-soap-messages/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>I Love Easy Extensibility</title><link>http://davybrion.com/blog/2009/03/i-love-easy-extensibility/</link> <comments>http://davybrion.com/blog/2009/03/i-love-easy-extensibility/#comments</comments> <pubDate>Tue, 10 Mar 2009 17:01:13 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1088</guid> <description><![CDATA[Welcome to episode 245 in my Love/Hate relationship with WCF. Today i had to add some technical logging to some infrastructure code. More specifically, we wanted to log the size of incoming and outgoing SOAP messages. If you're using something like the Request/Response service layer you do want to keep an eye on the size [...]]]></description> <content:encoded><![CDATA[<p>Welcome to episode 245 in my Love/Hate relationship with WCF.  Today i had to add some technical logging to some infrastructure code.  More specifically, we wanted to log the size of incoming and outgoing SOAP messages.  If you're using something like <a
href="http://davybrion.com/blog/2008/07/the-request-response-service-layer/">the Request/Response service layer</a> you do want to keep an eye on the size of those SOAP messages to make sure nobody is going overboard with the WCF batching.</p><p>I obviously already had my service, so i just needed something that i could plug in at the appropriate moment to record the size of incoming and outgoing SOAP messages.  Turns out this was extremely easy to do.  First, you need to write an inspector for the messages (which has to implement WCF's IDispatchMessageInspector interface):</p><p><code></p><div
style="font-family: Consolas; font-size: 9pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">MessageInspector</span> : <span
style="color: #2b91af;">IDispatchMessageInspector</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">readonly</span> <span
style="color: #2b91af;">ILog</span> logger = <span
style="color: #2b91af;">LogManager</span>.GetLogger(<span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">MessageInspector</span>));</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">object</span> AfterReceiveRequest(<span
style="color: blue;">ref</span> <span
style="color: #2b91af;">Message</span> request, <span
style="color: #2b91af;">IClientChannel</span> channel, <span
style="color: #2b91af;">InstanceContext</span> instanceContext)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (logger.IsInfoEnabled)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; logger.Info(<span
style="color: blue;">string</span>.Format(<span
style="color: #a31515;">&quot;request message size: ~{0} KB&quot;</span>, GetMessageLengthInKB(request)));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">null</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> BeforeSendReply(<span
style="color: blue;">ref</span> <span
style="color: #2b91af;">Message</span> reply, <span
style="color: blue;">object</span> correlationState)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (logger.IsInfoEnabled)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; logger.Info(<span
style="color: blue;">string</span>.Format(<span
style="color: #a31515;">&quot;response message size: ~{0} KB&quot;</span>, GetMessageLengthInKB(reply)));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">double</span> GetMessageLengthInKB(<span
style="color: #2b91af;">Message</span> message)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: #2b91af;">Math</span>.Round(<span
style="color: #2b91af;">Encoding</span>.UTF8.GetBytes(message.ToString()).Length / 1024d, 2);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>After that, you need a way to inject the MessageInspector into the behavior of your service.  So you need to define your own behavior first:</p><p><code></p><div
style="font-family: Consolas; font-size: 9pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">AddMessageInspectorBehaviorAttribute</span> : <span
style="color: #2b91af;">Attribute</span>, <span
style="color: #2b91af;">IServiceBehavior</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> Validate(<span
style="color: #2b91af;">ServiceDescription</span> serviceDescription, <span
style="color: #2b91af;">ServiceHostBase</span> serviceHostBase) {}</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> AddBindingParameters(<span
style="color: #2b91af;">ServiceDescription</span> serviceDescription, <span
style="color: #2b91af;">ServiceHostBase</span> serviceHostBase,</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Collection</span>&lt;<span
style="color: #2b91af;">ServiceEndpoint</span>&gt; endpoints, <span
style="color: #2b91af;">BindingParameterCollection</span> bindingParameters) {}</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> ApplyDispatchBehavior(<span
style="color: #2b91af;">ServiceDescription</span> serviceDescription, <span
style="color: #2b91af;">ServiceHostBase</span> serviceHostBase)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">foreach</span> (<span
style="color: #2b91af;">ChannelDispatcher</span> dispatcher <span
style="color: blue;">in</span> serviceHostBase.ChannelDispatchers)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">foreach</span> (<span
style="color: blue;">var</span> endpoint <span
style="color: blue;">in</span> dispatcher.Endpoints)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; endpoint.DispatchRuntime.MessageInspectors.Add(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">MessageInspector</span>());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>And then you apply that to your service:</p><p><code></p><div
style="font-family: Consolas; font-size: 9pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ServiceBehavior</span>(InstanceContextMode = <span
style="color: #2b91af;">InstanceContextMode</span>.PerCall)]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">AddMessageInspectorBehavior</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">WcfRequestProcessor</span> : <span
style="color: #2b91af;">IRequestProcessor</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: green;">// the service stuff...</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>And that was it! I was afraid i was going to have to figure out which one of WCF's 12.4 billion configuration options would make this possible but this actually didn't require any configuration at all.  Which is very nice, IMO.</p><p>On a side note, if anyone knows of a better way to calculate the real size of a SOAP message, please let me know <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F03%2Fi-love-easy-extensibility%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/03/i-love-easy-extensibility/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/03/i-love-easy-extensibility/"  data-text="I Love Easy Extensibility" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/03/i-love-easy-extensibility/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/03/i-love-easy-extensibility/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/03/i-love-easy-extensibility/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Abstracting Request State</title><link>http://davybrion.com/blog/2009/01/abstracting-request-state/</link> <comments>http://davybrion.com/blog/2009/01/abstracting-request-state/#comments</comments> <pubDate>Sat, 17 Jan 2009 15:19:43 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[ASP.NET]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=857</guid> <description><![CDATA[Sometimes it's useful to be able to store an object somewhere so you can easily access it for the duration of the current request, instead of having to pass it around with every method call that you make. That request could be an ASP.NET request, or a request in your WCF service layer. I used [...]]]></description> <content:encoded><![CDATA[<p>Sometimes it's useful to be able to store an object somewhere so you can easily access it for the duration of the current request, instead of having to pass it around with every method call that you make.  That request could be an ASP.NET request, or a request in your WCF service layer.  I used to resort to storing these objects in ThreadStatic fields (which is basically a static reference for each thread), thinking that it would be safe because only one thread handles a complete request.  Last week i read that some requests can <a
href="http://piers7.blogspot.com/2005/11/threadstatic-callcontext-and_02.html">be paused and resumed by another thread</a>.  If you're using ThreadStatic fields, this could lead so major issues which would be a royal pain in the ass to debug.  In order to prevent this possible problem, i wanted to have a safe way to keep state that should be available for the duration of a single request.</p><p>If your code executes in an ASP.NET environment, you can safely use the HttpContext.Current.Items dictionary for this.  If your code executes in a WCF environment, you can store these things in the OperationContext.  I don't want my code to be tightly coupled to either ASP.NET or WCF, so i wanted some kind of abstraction.  This is the approach that i came up with.</p><p>First, we have the IRequestState interface:</p><div><pre class="brush: csharp; title: ; notranslate">
    public interface IRequestState
    {
        T Get&lt;T&gt;(string key);
        void Store(string key, object something);
    }
</pre></div><p>This just offers a way to store objects and retrieve them.  That's pretty much al we need, right?</p><p>Then we have the ASP.NET implementation:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class AspNetRequestState : IRequestState
    {
        public T Get&lt;T&gt;(string key)
        {
            return (T)HttpContext.Current.Items[key];
        }
 
        public void Store(string key, object something)
        {
            HttpContext.Current.Items[key] = something;
        }
    }
</pre></div><p>Very simple stuff... the AspNetRequestState implementation simply uses the HttpContext.Current.Items dictionary underneath to store and retrieve the objects.</p><p>For WCF, it is slightly more complicated.  Every WCF call is an operation and it has a context as well, which is provided through the OperationContext class.  The OperationContext class doesn't have an Items dictionary like HttpContext does, but it does have a way to add extensions to the context.  We can use this extensions mechanism to store state which should be kept around for the duration of the current WCF operation.  First, we need to define our Extension:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class MyExtension : IExtension&lt;OperationContext&gt;
    {
        public MyExtension()
        {
            State = new Dictionary&lt;string, object&gt;();
        }
 
        public IDictionary&lt;string, object&gt; State { get; private set; }
 
        // we don't really need implementations for these methods in this case
        public void Attach(OperationContext owner) { }
        public void Detach(OperationContext owner) { }
    }
</pre></div><p>The IExtension interface that we must implement defines the Attach and Detach methods but we don't really need them for what we're trying to do.  This extension simply initializes a Dictionary instance and exposes it with a public getter.  Now we can easily create our WcfRequestState implementation:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class WcfRequestState : IRequestState
    {
        private static IDictionary&lt;string, object&gt; State
        {
            get
            {
                var extension = OperationContext.Current.Extensions.Find&lt;StateExtension&gt;();
 
                if (extension == null)
                {
                    extension = new StateExtension();
                    OperationContext.Current.Extensions.Add(extension);
                }
 
                return extension.State;
            }
        }
 
        public T Get&lt;T&gt;(string key)
        {
            if (State.ContainsKey(key))
            {
                return (T)State[key];
            }
 
            return default(T);
        }
 
        public void Store(string key, object something)
        {
            State[key] = something;
        }
    }
</pre></div><p>Pretty simple as well, and pretty similar to the AspNetRequestState implementation.  The AspNetRequestState implementation is able to simply use the HttpContext.Current.Items dictionary, which we can't use here.  So when we want to access the 'State' dictionary in this implementation, we look it up in the current OperationContext's Extensions collection.  If it's not there yet, we add a new instance of our MyExtension class to the OperationContext's Extensions collection.</p><p>Now we can use this wherever we need to store something for the duration of the current request, regardless of whether we're executing in an ASP.NET or WCF context.  Just configure your IoC container to create instances of AspNetRequestState whenever an IRequestState instance is needed in your WebApplication, or configure it to return WcfRequestState instances in your WCF service.  The code that needs to store some request state will no longer have to resort to using ThreadStatic fields, and it doesn't need to know about it's runtime environment either.  It merely needs an instance of IRequestState.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F01%2Fabstracting-request-state%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/01/abstracting-request-state/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/01/abstracting-request-state/"  data-text="Abstracting Request State" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/01/abstracting-request-state/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/01/abstracting-request-state/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/01/abstracting-request-state/feed/</wfw:commentRss> <slash:comments>21</slash:comments> </item> <item><title>Do Not .Dispose In The PreRender Event</title><link>http://davybrion.com/blog/2008/10/do-not-dispose-in-the-prerender-event/</link> <comments>http://davybrion.com/blog/2008/10/do-not-dispose-in-the-prerender-event/#comments</comments> <pubDate>Wed, 01 Oct 2008 19:43:31 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[ASP.NET]]></category> <category><![CDATA[Memory Management]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=472</guid> <description><![CDATA[We had this weird issue with a project at work... sometimes, the web application would just completely hang for a couple of minutes. A coworker started looking at the problem, and he quickly found out that in some cases, calls to the WCF service would just completely block. Even when debugging the web application and [...]]]></description> <content:encoded><![CDATA[<p>We had this weird issue with a project at work... sometimes, the web application would just completely hang for a couple of minutes. A coworker started looking at the problem, and he quickly found out that in some cases, calls to the WCF service would just completely block.  Even when debugging the web application and the WCF service on our development machines, so it wasn't an issue of throughput or concurrency or anything like that on the server.</p><p>We were clueless as to why the calls were actually blocking. We had a few scenarios that would <strong>usually</strong> (but not always) trigger the bug, but it also occurred in other situations, seemingly at random.  So my coworker spent many hours trying to find out why it was happening. After a lot of debugging on his part, he found out that sometimes our WCF proxies weren't being disposed, which left Channels to the service open which caused new proxies to block whenever the number of allowed concurrent channels was reached. My first reaction was "huh, how could that be? i'm disposing of them in the page's PreRender event...".</p><p>First of all, i'm far from an ASP.NET guru, so those of you who do know a lot about it probably already understand the problem. I figured that the PreRender event would always occur, and that it would be the best place to dispose the WCF proxy.  That turned out to be a two-for-one brain fart on my part.  First of all, the PreRender event is obviously not fired when you do a Server.Redirect or Server.Transfer, so whenever we navigated to another page, we did not dispose our WCF proxy.  Secondly, Page inherits IDisposable, which i completely missed apparently.  So, had i simply overridden the Dispose method and dispose the proxy in there before calling base.Dispose() and then we would've never had this problem to begin with.</p><p>Lesson of the day: no matter how careful you try to be, you can still fuck up pretty bad sometimes <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Update: i actually used the PreRenderComplete event instead of the PreRender event... still, a bad place to dispose of disposable objects <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F10%2Fdo-not-dispose-in-the-prerender-event%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/10/do-not-dispose-in-the-prerender-event/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/10/do-not-dispose-in-the-prerender-event/"  data-text="Do Not .Dispose In The PreRender Event" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/10/do-not-dispose-in-the-prerender-event/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/10/do-not-dispose-in-the-prerender-event/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/10/do-not-dispose-in-the-prerender-event/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>WCF And Large Amounts Of Data</title><link>http://davybrion.com/blog/2008/09/wcf-and-large-amounts-of-data/</link> <comments>http://davybrion.com/blog/2008/09/wcf-and-large-amounts-of-data/#comments</comments> <pubDate>Sun, 14 Sep 2008 11:00:02 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=400</guid> <description><![CDATA[If you're using my Request/Response service layer, or any other WCF service that might require sending large amounts of data over the wire, you quickly bump into some limits that WCF enforces by default. Among the billions of configuration options for WCF, there are luckily some options that allow you to easily send large amounts [...]]]></description> <content:encoded><![CDATA[<p>If you're using my Request/Response service layer, or any other WCF service that might require sending large amounts of data over the wire, you quickly bump into some limits that WCF enforces by default.  Among the billions of configuration options for WCF, there are luckily some options that allow you to easily send large amounts of data from a service to a client.</p><p>I typically use the following options:</p><p>For my binding configuration i usually set the maxReceivedMessageSize, maxStringContentLength and the maxArrayLength properties to their maximum values:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">bindings</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">netTcpBinding</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">binding</span><span
style="color: blue;"> </span><span
style="color: red;">name</span><span
style="color: blue;">=</span>"<span
style="color: blue;">MyTcpBinding</span>"<span
style="color: blue;"> </span><span
style="color: red;">maxReceivedMessageSize</span><span
style="color: blue;">=</span>"<span
style="color: blue;">2147483647</span>"<span
style="color: blue;"> </span><span
style="color: red;">receiveTimeout</span><span
style="color: blue;">=</span>"<span
style="color: blue;">00:30</span>"<span
style="color: blue;"> </span><span
style="color: red;">sendTimeout</span><span
style="color: blue;">=</span>"<span
style="color: blue;">00:30</span>"<span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">readerQuotas</span><span
style="color: blue;"> </span><span
style="color: red;">maxStringContentLength</span><span
style="color: blue;">=</span>"<span
style="color: blue;">8192</span>"<span
style="color: blue;"> </span><span
style="color: red;">maxArrayLength</span><span
style="color: blue;">=</span>"<span
style="color: blue;">20971520</span>"<span
style="color: blue;"> /&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">binding</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">netTcpBinding</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">bindings</span><span
style="color: blue;">&gt;</span></p></div><p></code></p><p>This example shows these settings for the netTcpBinding... i've also used them with the wsHttpBinding. Not sure how well it works with other bindings though.</p><p>I also set the maxItemsInObjectGraph setting of the DataContractSerializer to make sure i don't hit the default limit if i have to send a large object graph over the wire:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">behaviors</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">serviceBehaviors</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">behavior</span><span
style="color: blue;"> </span><span
style="color: red;">name</span><span
style="color: blue;">=</span>"<span
style="color: blue;">MyBehavior</span>"<span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">dataContractSerializer</span><span
style="color: blue;"> </span><span
style="color: red;">maxItemsInObjectGraph</span><span
style="color: blue;">=</span>"<span
style="color: blue;">2147483647</span>"<span
style="color: blue;">/&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">serviceMetadata</span><span
style="color: blue;"> /&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">behavior</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">serviceBehaviors</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">behaviors</span><span
style="color: blue;">&gt;</span></p></div><p></code></p><p>You have to apply these settings both server and client side to get it working properly and you need to refer to these settings in your service and endpoint settings:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">service</span><span
style="color: blue;"> </span><span
style="color: red;">name</span><span
style="color: blue;">=</span>"<span
style="color: blue;">Brion.Library.ServerSide.WCF.WcfRequestProcessor</span>"<span
style="color: blue;"> </span><span
style="color: red;">behaviorConfiguration</span><span
style="color: blue;">=</span>"<span
style="color: blue;">MyBehavior</span>"<span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">host</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">baseAddresses</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">add</span><span
style="color: blue;"> </span><span
style="color: red;">baseAddress</span><span
style="color: blue;">=</span>"<span
style="color: blue;">net.tcp://localhost/RequestProcessor</span>"<span
style="color: blue;">/&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">baseAddresses</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">host</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">endpoint</span><span
style="color: blue;"> </span><span
style="color: red;">contract</span><span
style="color: blue;">=</span>"<span
style="color: blue;">Brion.Library.Common.WCF.IWcfRequestProcessor</span>"<span
style="color: blue;"> </span><span
style="color: red;">binding</span><span
style="color: blue;">=</span>"<span
style="color: blue;">netTcpBinding</span>"</p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span
style="color: red;">bindingConfiguration</span><span
style="color: blue;">=</span>"<span
style="color: blue;">MyTcpBinding</span>"<span
style="color: blue;"> /&gt;</span></p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">service</span><span
style="color: blue;">&gt;</span></p></div><p></code></p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">client</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">endpoint</span><span
style="color: blue;"> </span><span
style="color: red;">address</span><span
style="color: blue;">=</span>"<span
style="color: blue;">net.tcp://localhost/RequestProcessor</span>"<span
style="color: blue;"> </span><span
style="color: red;">binding</span><span
style="color: blue;">=</span>"<span
style="color: blue;">netTcpBinding</span>"</p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span
style="color: red;">name</span><span
style="color: blue;">=</span>"<span
style="color: blue;">IRequestProcessor</span>"<span
style="color: blue;"> </span><span
style="color: red;">bindingConfiguration</span><span
style="color: blue;">=</span>"<span
style="color: blue;">MyTcpBinding</span>"<span
style="color: blue;"> </span><span
style="color: red;">behaviorConfiguration</span><span
style="color: blue;">=</span>"<span
style="color: blue;">MyBehavior</span>"</p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span
style="color: red;">contract</span><span
style="color: blue;">=</span>"<span
style="color: blue;">Brion.Library.Common.WCF.IWcfRequestProcessor</span>"<span
style="color: blue;"> /&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">client</span><span
style="color: blue;">&gt;</span></p></div><p></code></p><p>Now, i don't recommend sending such large amounts of data through WCF services... but in the case of using my Request/Response service layer, the amount of data you're sending over the wire pretty much depends on which kind of requests (and how many of them) you're batching so i think it's better to make sure that at least the configuration allows for it.  So obviously, it's best to keep an eye on the size of your messages to make sure you're not doing anything crazy.  Being able to send your entire database over the wire doesn't mean it's a good idea to actually do so <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F09%2Fwcf-and-large-amounts-of-data%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/09/wcf-and-large-amounts-of-data/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/09/wcf-and-large-amounts-of-data/"  data-text="WCF And Large Amounts Of Data" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/09/wcf-and-large-amounts-of-data/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/09/wcf-and-large-amounts-of-data/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/09/wcf-and-large-amounts-of-data/feed/</wfw:commentRss> <slash:comments>12</slash:comments> </item> <item><title>Easing The Pain Of WCF Debugging</title><link>http://davybrion.com/blog/2008/08/easing-the-pain-of-wcf-debugging/</link> <comments>http://davybrion.com/blog/2008/08/easing-the-pain-of-wcf-debugging/#comments</comments> <pubDate>Wed, 20 Aug 2008 18:56:05 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=349</guid> <description><![CDATA[WCF is pretty cool, i guess. It's quite powerful, and it's so configurable it even has options to control the speed of the CPU fans of the users of your service. Ok, maybe you can't really configure that, but with approximately 12.4 billion WCF configuration settings available to you, who knows? But the biggest problem [...]]]></description> <content:encoded><![CDATA[<p>WCF is pretty cool, i guess. It's quite powerful, and it's so configurable it even has options to control the speed of the CPU fans of the users of your service.  Ok, maybe you can't really configure that, but with approximately 12.4 billion WCF configuration settings available to you, who knows? But the biggest problem i have with WCF is the painful debugging experience when something goes wrong.</p><p>Ever got a client-side exception that looked like this?</p><div><pre class="brush: plain; title: ; notranslate">
[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
   System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) +73
   System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +110

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:29:59.8590000'.]
   System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +183
   System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +54
   System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +32
   System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count, TimeSpan timeout) +32
   System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count) +53
   System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) +37
   System.Net.Security.NegotiateStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +131
   System.Net.Security.NegotiateStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +28
   System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +223

[IOException: The read operation failed, see inner exception.]
   System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +333
   System.Net.Security.NegotiateStream.Read(Byte[] buffer, Int32 offset, Int32 count) +79
   System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +72

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:29:59.8590000'.]
   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +7594687
   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData, Int32 type) +275
</pre></div><p>Rather messy, no? Does it give you any clue as to what could possibly be wrong? Nope. This particular client-side exception occurs when something goes wrong server-side, at some point after you've already returned your return value in your service implementation.  Of course, you don't actually see it happening server-side. So i tried setting IncludeExceptionDetailInFaults to true on the service implementation... didn't make a difference.  I set IncludeExceptionDetailInFaults to true on the service host but that didn't work either. Sigh.</p><p>After some Live Searching (i was actually googling, but let's make Microsoft think at least someone outside of Redmond uses Live Search) i discovered that you can enable WCF tracing.  Bingo! Why didn't Juval Lowy's book mention this? It's supposed to be the WCF Bible.... Oh well, thanks to Google, i mean Live Search, we now know how to enable WCF's tracing:</p><div><pre class="brush: xml; title: ; notranslate">
  &lt;system.diagnostics&gt;
    &lt;trace autoflush=&quot;true&quot; /&gt;
    &lt;sources&gt;
      &lt;source name=&quot;System.ServiceModel&quot;
              switchValue=&quot;Information, ActivityTracing&quot;
              propagateActivity=&quot;true&quot;&gt;
        &lt;listeners&gt;
          &lt;add name=&quot;wcfTraceListener&quot; type=&quot;System.Diagnostics.XmlWriterTraceListener&quot; initializeData=&quot;WcfTrace.svclog&quot; /&gt;
        &lt;/listeners&gt;
      &lt;/source&gt;
    &lt;/sources&gt;
  &lt;/system.diagnostics&gt;
</pre></div><p>You can also use the Service Configuration Editor tool which is available in the Windows SDK, but spare yourself the pain of that tool and just copy/paste this xml in your config file.</p><p>Now run the service again, and do whatever it was that triggered the weird client-side exception.  After the exception occurred, open the WcfTrace.svclog file with either an editor (it's not very readable though) or with the Microsoft Service Trace Viewer tool (which is not too bad actually).</p><p>When i opened my trace output, i immediately saw a red item in the Activity list... so i clicked on it, and i finally saw the problem:</p><p>There was an error while trying to serialize parameter http://tempuri.org/:ProcessReadOnlyRequestsResult. The InnerException message was 'Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota. '.  Please see InnerException for more details.</p><p>There we go... the client-side exception was terribly useless, but this is the best kind of exception: not only is it clear about what's wrong, it even gives you the solution to the problem.  Btw, if you get that client-side exception, it doesn't mean that your problem will be the same as the one listed here.  It could literally be anything if it doesn't happen inside of your service implementation.  I've seen the same client-side exception when one type somewhere in the object graph didn't have a DataContract attribute, for instance.</p><p>So anyways, do yourself a favor and enable WCF tracing while you're still in development... it could save you a lot of time.</p><p>Oh and bonus points go to whoever points out which of WCF's many configuration settings actually make the real exception appear in the client-side stacktrace <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F08%2Feasing-the-pain-of-wcf-debugging%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/08/easing-the-pain-of-wcf-debugging/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/08/easing-the-pain-of-wcf-debugging/"  data-text="Easing The Pain Of WCF Debugging" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/08/easing-the-pain-of-wcf-debugging/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/08/easing-the-pain-of-wcf-debugging/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/08/easing-the-pain-of-wcf-debugging/feed/</wfw:commentRss> <slash:comments>16</slash:comments> </item> <item><title>Batching++</title><link>http://davybrion.com/blog/2008/07/batching/</link> <comments>http://davybrion.com/blog/2008/07/batching/#comments</comments> <pubDate>Wed, 30 Jul 2008 19:25:36 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=244</guid> <description><![CDATA[The usual example: &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; dispatcher.Add(new GetProductCategoriesRequest(), new GetSuppliersRequest()); &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; View.ProductCategories = dispatcher.Get&#60;GetProductCategoriesResponse&#62;().ProductCategories; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; View.Suppliers = dispatcher.Get&#60;GetSuppliersResponse&#62;().Suppliers; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; View.DataBind(); Thanks to my request/response service layer, those are two service requests that will be performed in one service call. On the server side, these two [...]]]></description> <content:encoded><![CDATA[<p>The usual example:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dispatcher.Add(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductCategoriesRequest</span>(), <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetSuppliersRequest</span>());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.ProductCategories = dispatcher.Get&lt;<span
style="color: #2b91af;">GetProductCategoriesResponse</span>&gt;().ProductCategories;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.Suppliers = dispatcher.Get&lt;<span
style="color: #2b91af;">GetSuppliersResponse</span>&gt;().Suppliers;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.DataBind();</p></div><p></code></p><p>Thanks to my <a
href="http://davybrion.com/blog/2008/07/the-request-response-service-layer/">request/response service layer</a>, those are two service requests that will be performed in one service call.  On the server side, these two requests are dealt with separately.  But they merely retrieve data from the database.  Wouldn't it be cool if those 2 queries were performed in one database roundtrip instead of two?  Wouldn't it be cool if we could batch the queries that will be performed by read-only service requests into a single database roundtrip? It sure as hell would be. Implementing this was one of those irresistible challenges you just can't say no to, so from now on we can actually do this.  I'm not gonna get into the actual implementation of how I got it working (check the code in the library for that if you're interested), but i will show you how you can do this in your application.</p><p>First of all, if you have requests that merely return data, inherit from ReadOnlyRequest instead of the usual Request type:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductCategoriesRequest</span> : <span
style="color: #2b91af;">ReadOnlyRequest</span> {}</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetSuppliersRequest</span> : <span
style="color: #2b91af;">ReadOnlyRequest</span> {}</p></div><p></code></p><p>The handlers for these requests should inherit from the ReadOnlyRequestHandler base class instead of the usual RequestHandler class.  Btw, my ReadOnlyRequestHandler class inherits from my UoWRequestHandler class, which requires a IUnitOfWork instance to be passed to the constructor.  So we need to put an IUnitOfWork parameter into the constructor along with our other dependencies if we want the IOC container (or the request processor) to pass us a valid IUnitOfWork instance.</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductCategoriesHandler</span> : <span
style="color: #2b91af;">ReadOnlyRequestHandler</span>&lt;<span
style="color: #2b91af;">GetProductCategoriesRequest</span>&gt;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">readonly</span> <span
style="color: #2b91af;">IRepository</span>&lt;<span
style="color: #2b91af;">ProductCategory</span>&gt; repository;</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> GetProductCategoriesHandler(<span
style="color: #2b91af;">IUnitOfWork</span> unitOfWork, <span
style="color: #2b91af;">IRepository</span>&lt;<span
style="color: #2b91af;">ProductCategory</span>&gt; repository)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; : <span
style="color: blue;">base</span>(unitOfWork)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">this</span>.repository = repository;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: blue;">void</span> AddQueries(<span
style="color: #2b91af;">IQueryBatcher</span> queryBatcher, <span
style="color: #2b91af;">GetProductCategoriesRequest</span> request)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; queryBatcher.AddCriteria(<span
style="color: #a31515;">"categories"</span>, repository.CriteriaForAll());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: #2b91af;">Response</span> GetResults(<span
style="color: #2b91af;">IQueryBatcher</span> queryBatcher, <span
style="color: #2b91af;">GetProductCategoriesRequest</span> request)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> categories = queryBatcher.GetEnumerableResult&lt;<span
style="color: #2b91af;">ProductCategory</span>&gt;(<span
style="color: #a31515;">"categories"</span>);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductCategoriesResponse</span> { ProductCategories = categories.ToDTOs() };</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>The ReadOnlyRequestHandler class defines two abstract methods: the AddQueries and GetResults method.  Both are passed an instance of IQueryBatcher and the actual request object so you can use the request parameters if there are any.</p><p>In the AddQueries method, you simply add the queries this request needs to perform to the batcher (with a string key value of course for later retrieval), and in the GetResults method you can get the results (with the key values used in AddQueries) back from the batcher and you can construct your Response object.  The GetResults method will be called after each ReadOnlyRequestHandler for the current request batch has added the queries to be performed to the batcher.  The queries are then all executed, and each ReadOnlyRequestHandler will have its GetResults method called so each handler can construct the proper response.</p><p>And that's it basically... The calling code doesn't even change.</p><p>Now there are obviously some limitations. If you mix ReadOnlyRequests with other Requests, then each ReadOnlyRequest will be handled as if it were a regular Request and they will each get their very own IQueryBatcher instance.  I don't think there's any strategy to automagically determine which ReadOnlyRequests can be batched together while still correctly executing the other Requests since those requests might influence the results of ReadOnlyRequests that are present further in the batch.</p><p>Anyways, you can find an updated version of the library <a
href="http://davybrion.com/blog/stuff/">here</a>.  Check it out, it's some pretty slick shit, if i do say so myself <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><p>Note: i only added this stuff today, so the previous build (080729) doesn't have this yet, in case you only downloaded that today, and the stats show that some of you actually did download it <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F07%2Fbatching%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/07/batching/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/07/batching/"  data-text="Batching++" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/07/batching/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/07/batching/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/07/batching/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>The Request/Response Service Layer</title><link>http://davybrion.com/blog/2008/07/the-request-response-service-layer/</link> <comments>http://davybrion.com/blog/2008/07/the-request-response-service-layer/#comments</comments> <pubDate>Sun, 27 Jul 2008 11:07:15 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Patterns]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=211</guid> <description><![CDATA[Update: i also have a complete series of posts on this which you may find interesting. Introduction When you're trying to design a service layer API, there are two things you always need to be very careful of. The first is making sure the API isn't chatty. A service layer is usually deployed on another [...]]]></description> <content:encoded><![CDATA[<p>Update: i also have a complete <a
href="http://davybrion.com/blog/2009/11/requestresponse-service-layer-series/">series of posts</a> on this which you may find interesting.</p><h2>Introduction</h2><p>When you're trying to design a service layer API, there are two things you always need to be very careful of. The first is making sure the API isn't chatty. A service layer is usually deployed on another physical machine than the client layer, so you want clients to be able to do everything they need to do with a minimum of roundtrips, because those are after all rather expensive.  The second thing you want to avoid is the implicit coupling between the client of the service and the service itself.  In your quest to avoid the chatty interface, you might start grouping several service operations together in more coarse-grained operations to avoid the chatty communication that might otherwise occur.  This can be good from a performance point of view, but it usually introduces a certain implicit coupling between the service and the client, because a specific grouping of operations might be beneficial to one client, but might be completely inappropriate to another type of client of the service.</p><p>I really had difficulties coming up with an approach that offered nice coarse-grained service interfaces while at the same time making sure the interfaces weren't too 'driven' by a client's specific requirements.  So i basically wanted a way to keep my service operations as specific as they could be (very fine-grained), while avoiding the pitfall of chatty communication by batching calls to the service layer together whenever it makes sense <strong>from the client's point of view</strong>.  I eventually ended up with an approach that i've already documented <a
href="http://davybrion.com/blog/2008/06/batching-wcf-calls/">here</a> and <a
href="http://davybrion.com/blog/2008/07/batching-wcf-calls-take-2/">here</a>.  Read those posts first before continuing with this post because the rest of this post builds upon the content of the previous posts.</p><p>The idea is to basically consider each <em>service operation</em> as a <em>request</em> which can have a <em>response</em>. For each request that you define, you need to provide a handler which does whatever it needs to do to handle the request and returns a response, or an empty response if no response is needed for a specific request.  You then only need one service method which receives incoming requests, delegates them to the proper handlers, and returns each response in the order of the incoming requests. On a side note: this approach probably doesn't sit well with many SOA people, but then again, i couldn't care less about SOA. I just want good software no matter what acronym i can use to describe it.</p><p>Anyway, i like this approach so much that i wanted to make it available to whoever is interested in it.  You can find it in my open source library which you can find <a
href="http://davybrion.com/blog/stuff/">here</a>. I won't go into the details of the implementation, because those have mostly been covered already in my previous posts on this subject.  The rest of this post focuses solely on how you can use this approach in your projects.</p><h2>Defining Requests and Responses</h2><p>The following two base classes need to be used to define request and response types:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">namespace</span> Brion.Library.Common.Messaging</p><p
style="margin: 0px;">{</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">Request</span> {}</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">Response</span> { }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">}</p></div><p></code></p><p>Suppose you have a service operation that retrieves a list of products based on some parameters the user could provide in the UI. You would define the request like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductOverviewsRequest</span> : <span
style="color: #2b91af;">Request</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">string</span> NamePattern { <span
style="color: blue;">get</span>; <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">int</span>? CategoryId { <span
style="color: blue;">get</span>; <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">int</span>? SupplierId { <span
style="color: blue;">get</span>; <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>And the response would look like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductOverviewsResponse</span> : <span
style="color: #2b91af;">Response</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">ProductOverviewDTO</span>[] Products { <span
style="color: blue;">get</span>; <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>Keep in mind that these types always need to be marked with the Serializable attribute and that these types need to be in an assembly that you can share between both the client and the service.</p><h2>Handling Requests</h2><p>Incoming requests are handled by a class which implements the IRequestProcessor interface:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">namespace</span> Brion.Library.Common.Messaging</p><p
style="margin: 0px;">{</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">interface</span> <span
style="color: #2b91af;">IRequestProcessor</span> : <span
style="color: #2b91af;">IDisposable</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Response</span>[] Process(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requests);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">}</p></div><p></code></p><p>For each request that is received, the request processor will create a request handler which must be of the type IRequestHandler&lt;TRequest&gt; where TRequest is the type of the request instance. The request object is then passed along to the handler's Handle method, which will return a proper Response object.</p><p>The simplest way to create a request handler is to inherit from the RequestHandler&lt;TRequest&gt; class, like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductOverviewsHandler</span> :</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Brion.Library.ServerSide.Messaging.<span
style="color: #2b91af;">RequestHandler</span>&lt;<span
style="color: #2b91af;">GetProductOverviewsRequest</span>&gt;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">IProductRepository</span> ProductRepository { <span
style="color: blue;">get</span>; <span
style="color: blue;">private</span> <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> GetProductOverviewsHandler(<span
style="color: #2b91af;">IProductRepository</span> productRepository)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ProductRepository = productRepository;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: #2b91af;">Response</span> Handle(<span
style="color: #2b91af;">GetProductOverviewsRequest</span> request)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> products = ProductRepository.FindAll(request.NamePattern, request.SupplierId,</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; request.CategoryId);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductOverviewsResponse</span> { Products = products.ToOverviewDTOs() };</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>The request processor uses the Castle Windsor Inversion Of Control container to resolve and create the instances of the request handler types. This allows you to use <a
href="http://davybrion.com/blog/2007/07/introduction-to-dependency-injection/">dependency injection</a> for your request handlers. In the example posted above, you can see that the constructor of the handler takes an IProductRepository instance. Because the Windsor container also knows about the IProductRepository component in my application, it can correctly instantiate the GetProductOverviewsHandler instance with a valid IProductRepository instance.  Keep in mind that this is optional though. You don't have to use dependency injection for your request handlers if you don't want to.</p><p>If you do want to use it, your application will have to use the same Windsor container instance as this library does. To make this possible, the library contains the following class:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">namespace</span> Brion.Library.Common</p><p
style="margin: 0px;">{</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">static</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">IoC</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: #2b91af;">IWindsorContainer</span> container = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">WindsorContainer</span>();</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;summary&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> Gets/Sets the current Windsor container. Applications can either use</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> the reference to the container that this property provides, or they</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> can set their own reference through the setter. </span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;/summary&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">static</span> <span
style="color: #2b91af;">IWindsorContainer</span> Container { <span
style="color: blue;">get</span>; <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">}</p></div><p></code></p><p>By default, an empty container is created which you can access (and thus, configure) through the IoC.Container property.  Or if you want the library to use your own Windsor container instance you can simply set the instance and then the library will use your container.  For the moment, it is not possible to use another container (like StructureMap or Unity) yet, but that possibility might be added if people want it, or if someone submits a patch <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Obviously, you need to register your request handlers somewhere in your application code, preferably before you start hosting the service layer.  You can do that like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Brion.Library.ServerSide.<span
style="color: #2b91af;">ComponentRegistration</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .RegisterRequestHandlersFrom(<span
style="color: #2b91af;">Assembly</span>.GetExecutingAssembly());</p></div><p></code></p><p>That basically registers each valid request handler (each type that inherits from the RequestHandler class provided by the library) that is present in the given assembly.  You can also very easily provide your own custom base request handler, in case you want to provide some extra stuff.  You'd simply need to inherit from the library's RequestHandler class, add whatever it is you need, and let your request handlers inherit from your new class instead of directly inheriting from the library's RequestHandler.</p><h2>Hosting The Service Layer</h2><p>There are a lot of options for hosting the service layer. Most people will probably host it as a WCF service so we'll cover that scenario here. The service contract looks like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">namespace</span> Brion.Library.Common.WCF</p><p
style="margin: 0px;">{</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ServiceContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">interface</span> <span
style="color: #2b91af;">IWcfRequestProcessor</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">OperationContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ServiceKnownType</span>(<span
style="color: #a31515;">"GetKnownTypes"</span>, <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">KnownTypeProvider</span>))]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Response</span>[] Process(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requests);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">}</p></div><p></code></p><p>This is practically identical to the IRequestProcessor interface shown earlier in the article. The difference is that IRequestProcessor uses no WCF attributes.  The actual implementation of IRequestProcessor is completely decoupled from WCF as well so you can use this approach without having to use WCF if you want to.  The implementation of the IWcfRequestProcessor simply forwards each call to the real request processor.</p><p>Notice the usage of the <a
href="http://davybrion.com/blog/2008/07/the-known-type-provider/">KnownTypeProvider class</a>. This makes sure that each of your Request or Response derived types will be properly recognized as a KnownType.  All you have to do is register them, like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">KnownTypeProvider</span>.RegisterDerivedTypesOf&lt;<span
style="color: #2b91af;">Request</span>&gt;(sharedAssembly);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">KnownTypeProvider</span>.RegisterDerivedTypesOf&lt;<span
style="color: #2b91af;">Response</span>&gt;(sharedAssembly);</p></div><p></code></p><p>This registers each Request or Response derived type from the sharedAssembly reference (which is a reference to the shared assembly containing the request and response types) with the KnownTypeProvider.  You need to do this before you start hosting the service.  It's best to combine this task with the registration of your request handlers.</p><p>The actual hosting of the service is typical WCF and is entirely up to you.  Here's a simple example of self-hosting the service in a console app:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">services</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">service</span><span
style="color: blue;"> </span><span
style="color: red;">name</span><span
style="color: blue;">=</span>"<span
style="color: blue;">Brion.Library.ServerSide.WCF.WcfRequestProcessor</span>"<span
style="color: blue;"> </span><span
style="color: red;">behaviorConfiguration</span><span
style="color: blue;">=</span>"<span
style="color: blue;">MyBehavior</span>"<span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color: #a31515;">endpoint</span><span
style="color: blue;"> </span><span
style="color: red;">contract</span><span
style="color: blue;">=</span>"<span
style="color: blue;">Brion.Library.Common.WCF.IWcfRequestProcessor</span>"<span
style="color: blue;"> </span><span
style="color: red;">binding</span><span
style="color: blue;">=</span>"<span
style="color: blue;">netNamedPipeBinding</span>"<span
style="color: blue;"> </span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span
style="color: red;">bindingConfiguration</span><span
style="color: blue;">=</span>"<span
style="color: blue;">MyNamedPipeBinding</span>"<span
style="color: blue;"> </span><span
style="color: red;">address</span><span
style="color: blue;">=</span>"<span
style="color: blue;">net.pipe://localhost/RequestProcessor</span>"<span
style="color: blue;">/&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">service</span><span
style="color: blue;">&gt;</span></p><p
style="margin: 0px;"><span
style="color: blue;">&nbsp; &nbsp; &lt;/</span><span
style="color: #a31515;">services</span><span
style="color: blue;">&gt;</span></p></div><p></code></p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">using</span> (<span
style="color: blue;">var</span> host = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">ServiceHost</span>(<span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">WcfRequestProcessor</span>)))</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; host.Open();</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Console</span>.WriteLine(<span
style="color: #a31515;">"press ENTER to quit"</span>);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Console</span>.ReadLine();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>You'll most likely prefer an alternative way of hosting the service, but again, that is entirely up to you and is typical WCF stuff.  All you need to know is that the service contract is the Brion.Library.Common.WCF.IWcfRequestProcessor interface, and the actual implementation of the service is the Brion.Library.ServerSide.WCF.WcfRequestProcessor class.</p><h2>Communicating With The Service Layer</h2><p>In your client layer, you can choose between using a direct proxy type for the IWcfRequestProcessor service, or you can use the Dispatcher class.  The Dispatcher class is somewhat of a wrapper around the direct proxy to make it easier to use and to get a nicer syntax.  The Dispatcher class implements the IDispatcher interface:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">namespace</span> Brion.Library.ClientSide.Messaging</p><p
style="margin: 0px;">{</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">interface</span> <span
style="color: #2b91af;">IDispatcher</span> : <span
style="color: #2b91af;">IDisposable</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">IEnumerable</span>&lt;<span
style="color: #2b91af;">Request</span>&gt; Requests { <span
style="color: blue;">get</span>; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">IEnumerable</span>&lt;<span
style="color: #2b91af;">Response</span>&gt; Responses { <span
style="color: blue;">get</span>; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">void</span> Add(<span
style="color: #2b91af;">Request</span> request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">void</span> Add(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requestsToAdd);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">void</span> Add(<span
style="color: blue;">string</span> key, <span
style="color: #2b91af;">Request</span> request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TResponse Get&lt;TResponse&gt;() <span
style="color: blue;">where</span> TResponse : <span
style="color: #2b91af;">Response</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TResponse Get&lt;TResponse&gt;(<span
style="color: blue;">string</span> key) <span
style="color: blue;">where</span> TResponse : <span
style="color: #2b91af;">Response</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TResponse Get&lt;TResponse&gt;(<span
style="color: #2b91af;">Request</span> request) <span
style="color: blue;">where</span> TResponse : <span
style="color: #2b91af;">Response</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">void</span> Clear();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">}</p></div><p></code></p><p>There are 3 implementations of this interface.  The first is the Dispatcher class itself, which has a dependency on an IRequestProcessor instance.  The second is the WcfDispatcher class which inherits from the Dispatcher class and will supply its base class with a RequestProcessorProxy instance to satisfy the IRequestProcessor dependency.  The third implementation is the DispatcherStub class, which is only useful for your tests.  If you want to use dependency injection through the container, you can register the correct components at client start-up time like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Brion.Library.ClientSide.<span
style="color: #2b91af;">ComponentRegistration</span>.RegisterDispatcherForWcfUsage();</p></div><p></code></p><p>The container will then have the correct configuration to provide you with IDispatcher instances that will correctly use the RequestProcessorProxy underneath. If you don't want to use the container client-side, you can simply instantiate instances of the WcfDispatcher class.</p><p>So, how do you use the dispatcher? It's pretty easy really.  Suppose you want to dispatch two requests to the service, you could do so like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dispatcher.Add(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductCategoriesRequest</span>(), <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetSuppliersRequest</span>());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.ProductCategories = dispatcher.Get&lt;<span
style="color: #2b91af;">GetProductCategoriesResponse</span>&gt;().ProductCategories;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.Suppliers = dispatcher.Get&lt;<span
style="color: #2b91af;">GetSuppliersResponse</span>&gt;().Suppliers;</p></div><p></code></p><p>The requests won't be dispatched to the service until you actually call one of the Get method overloads for the first time.  So you can add as much requests as you like, they won't be dispatched until you try to retrieve a response. And when those requests are dispatched, it is done in only one roundtrip.</p><p>If you just want to dispatch a single request, you could do so like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> request = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductOverviewsRequest</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; { NamePattern = name, CategoryId = productCategoryId, SupplierId = supplierId };</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> response = dispatcher.Get&lt;<span
style="color: #2b91af;">GetProductOverviewsResponse</span>&gt;(request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.Products = response.Products;</p></div><p></code></p><p>Keep in mind that you do need to define the service endpoint in your client-side application's configuration file. You also need to register the KnownTypes client-side before you start using the Dispatcher or the service proxy in the manner discussed earlier.</p><h2>Stubbing The Service Layer During Testing</h2><p>If you write tests for your client-side code, you'll be glad to hear that i've included a DispatcherStub class which makes it easy to prepare responses to return and to inspect requests that were sent from the code you're testing.  The approach i outlined in this post doesn't really lend itself to easy mocking, so the DispatcherStub class makes it all much easier.</p><p>First of all, make sure your client code always uses references of the IDispatcher type instead of directly using the Dispatcher or WcfDispatcher types.  Then in your tests, inject DispatcherStub instances instead of real Dispatchers.  The DispatcherStub class provides a few extra methods which you can use in your tests:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Test</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> RetrievesCategoriesAndSuppliersOnLoad()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> categoriesToReturn = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">ProductCategoryDTO</span>[0];</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> suppliersToReturn = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">SupplierDTO</span>[0];</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dispatcher.SetResponsesToReturn(</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductCategoriesResponse</span> { ProductCategories = categoriesToReturn },</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetSuppliersResponse</span> { Suppliers = suppliersToReturn });</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view.Expect(v =&gt; v.ProductCategories = categoriesToReturn);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view.Expect(v =&gt; v.Suppliers = suppliersToReturn);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view.Expect(v =&gt; v.DataBind());</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; mocks.ReplayAll();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CreateController().Load();</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; view.VerifyAllExpectations();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Assert</span>.IsNotNull(dispatcher.GetRequest&lt;<span
style="color: #2b91af;">GetProductCategoriesRequest</span>&gt;());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Assert</span>.IsNotNull(dispatcher.GetRequest&lt;<span
style="color: #2b91af;">GetSuppliersRequest</span>&gt;());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>The SetResponsesToReturn and GetRequest methods make it much easier to stub the service layer than traditional mocking would.</p><p>Something you'll often want to test is that requests have been sent with the correct parameters:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> request = dispatcher.GetRequest&lt;<span
style="color: #2b91af;">GetProductOverviewsRequest</span>&gt;();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Assert</span>.AreEqual(productPattern, request.NamePattern);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Assert</span>.AreEqual(categoryId, request.CategoryId);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Assert</span>.AreEqual(supplierId, request.SupplierId);</p></div><p></code></p><h2>Time to wrap it up</h2><p>Again, i really like this approach. Unfortunately i haven't had the chance to use this in a real project yet, but based on my experiments i'm already very happy with it and am looking forward to use this in a real project. If you'd like to use this approach, download the library <a
href="http://davybrion.com/blog/stuff/">here</a>, play around with it, try it out, try to break it, and let me know what needs to be fixed/changed/added.  Or send patches <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F07%2Fthe-request-response-service-layer%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/07/the-request-response-service-layer/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/07/the-request-response-service-layer/"  data-text="The Request/Response Service Layer" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/07/the-request-response-service-layer/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/07/the-request-response-service-layer/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/07/the-request-response-service-layer/feed/</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>The Known Type Provider</title><link>http://davybrion.com/blog/2008/07/the-known-type-provider/</link> <comments>http://davybrion.com/blog/2008/07/the-known-type-provider/#comments</comments> <pubDate>Mon, 21 Jul 2008 12:35:32 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=193</guid> <description><![CDATA[Manually dealing with KnownTypes in WCF is a bit of a pain. Well, at least if you have more than a few derived types you want your WCF services to serialize/deserialize. Luckily for us, there is a way to do this automatically. Using the ServiceKnownType attribute you can specify a class and a static method [...]]]></description> <content:encoded><![CDATA[<p>Manually dealing with KnownTypes in WCF is a bit of a pain. Well, at least if you have more than a few derived types you want your WCF services to serialize/deserialize.  Luckily for us, there is a way to do this automatically.  Using the <a
href="http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceknowntypeattribute.aspx">ServiceKnownType</a> attribute you can specify a class and a static method of that class which will provide the Known Types.  An example of this can be found on my ever-recurring Process service method:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">OperationContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ServiceKnownType</span>(<span
style="color: #a31515;">"GetKnownTypes"</span>, <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">KnownTypeProvider</span>))]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Response</span>[] Process(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requests);</p></div><p></code></p><p>This works, but i don't want to write a class every time i want to specify some known types of a base type in a service method.  So i modified that KnownTypeProvider class so that we can now do the following:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">KnownTypeProvider</span>.RegisterDerivedTypesOf&lt;<span
style="color: #2b91af;">Request</span>&gt;(mySharedAssembly);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">KnownTypeProvider</span>.RegisterDerivedTypesOf&lt;<span
style="color: #2b91af;">Response</span>&gt;(mySharedAssembly);</p></div><p></code></p><p>This registers each derived type of Request and Response in the mySharedAssembly reference (of type Assembly) with the KnownTypeProvider.  You can register as many known types for as many base types as you want.  Obviously, you have to do this before you start hosting your service. You also need to do this client-side, before you start using your service proxies.</p><p>You're probably thinking "wait, won't that return all registered known types for every service call where you use this stuff?".  That wouldn't be good, so i took care of that. The ServiceKnownType attribute of WCF requires your class to implement a method which receives a parameter of type ICustomAttributeProvider and which returns a list of types.  The ICustomAttributeProvider parameter is actually a MethodInfo instance at runtime.  This makes it possible to inspect the current service method's parameters and return type.  That information makes it possible to only return the KnownTypes that are relevant to the current service call.  All of this sounds expensive with regards to performance, so obviously this is all cached... so you only take the performance hit on the very first request of each service method where you use this.</p><p>The KnownTypeProvider makes it extremely easy to register your KnownTypes in a generic way, can be reused across multiple service methods and it only returns the relevant KnownTypes for each service method.  And it does so with a minimum of performance overhead.</p><p>You can find the code in my <a
href="http://davybrion.com/publicsvn/Brion.Library/Brion.Library.Common/WCF/KnownTypeProvider.cs">public svn repository</a> as a part of my utility library (the tests can be found <a
href="http://davybrion.com/publicsvn/Brion.Library/Brion.Library.Tests/Common/WCF/KnownTypeProviderTests.cs">here</a>).  At this moment it is one of the only classes in the library, because i still have to add some other stuff before i'll put a 'proper release' online <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F07%2Fthe-known-type-provider%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/07/the-known-type-provider/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/07/the-known-type-provider/"  data-text="The Known Type Provider" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/07/the-known-type-provider/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/07/the-known-type-provider/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/07/the-known-type-provider/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Can someone tell me why i shouldn&#8217;t drop WCF?</title><link>http://davybrion.com/blog/2008/07/can-someone-tell-me-why-i-shouldnt-drop-wcf/</link> <comments>http://davybrion.com/blog/2008/07/can-someone-tell-me-why-i-shouldnt-drop-wcf/#comments</comments> <pubDate>Sat, 12 Jul 2008 14:39:24 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=168</guid> <description><![CDATA[I've written a few posts about WCF lately... mostly about how to batch WCF service calls. In case you didn't know, i consider batching support a MUST-HAVE feature. Since then, my WCF services all extend the following interface: &#160;&#160;&#160; [ServiceContract] &#160;&#160;&#160; public interface IService : IDisposable &#160;&#160;&#160; { &#160;&#160;&#160; &#160;&#160;&#160; /// &#60;summary&#62; &#160;&#160;&#160; &#160;&#160;&#160; /// [...]]]></description> <content:encoded><![CDATA[<p>I've written a few posts about WCF lately... mostly about <a
href="http://davybrion.com/blog/2008/06/batching-wcf-calls/">how to batch WCF service calls</a>.  In case you didn't know, i consider batching support a MUST-HAVE feature.  Since then, my WCF services all extend the following interface:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ServiceContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">interface</span> <span
style="color: #2b91af;">IService</span> : <span
style="color: #2b91af;">IDisposable</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;summary&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> Processes each request within the same service call</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;/summary&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;param name="requests"&gt;</span><span
style="color: green;">each request</span><span
style="color: gray;">&lt;/param&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;returns&gt;</span><span
style="color: green;">the corresponding responses</span><span
style="color: gray;">&lt;/returns&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">OperationContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ServiceKnownType</span>(<span
style="color: #a31515;">"GetKnownTypes"</span>, <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">KnownTypeProvider</span>))]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Response</span>[] Process(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requests);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>I wanted to keep providing specific service methods for each kind of request, but each service implementation would delegate the handling of the requests to the Process method, which in turn would delegate the handling of the request to a specific request handler type which was associated with the request type.  So basically, all of these specific service contracts which extend this service don't really offer me anything extra.</p><p>So now i'm wondering why i'm even bothering with the specific services anymore... it only leads to more work: more service interfaces and more proxies and in the end, everything is routed to the Process method.  So what's the point of these specific services anymore if you don't have batching support out of the box? If i have to go with a generic Process method to get batching support (again, which i consider a MUST-HAVE feature), why am i even bothering with Services at all? Essentially, i'm using a service bus with WCF.  Why shouldn't i just move to NServiceBus which is actally perfectly suited for this kind of work?</p><p>For the record, i'm not trying to flame or anything... i really want to get some answers to the following question: why shouldn't i drop WCF and the whole service layer thing in favor of a real service bus and Messaging in general?</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F07%2Fcan-someone-tell-me-why-i-shouldnt-drop-wcf%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/07/can-someone-tell-me-why-i-shouldnt-drop-wcf/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/07/can-someone-tell-me-why-i-shouldnt-drop-wcf/"  data-text="Can someone tell me why i shouldn&#8217;t drop WCF?" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/07/can-someone-tell-me-why-i-shouldnt-drop-wcf/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/07/can-someone-tell-me-why-i-shouldnt-drop-wcf/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/07/can-someone-tell-me-why-i-shouldnt-drop-wcf/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Batching WCF calls, Take 2</title><link>http://davybrion.com/blog/2008/07/batching-wcf-calls-take-2/</link> <comments>http://davybrion.com/blog/2008/07/batching-wcf-calls-take-2/#comments</comments> <pubDate>Tue, 01 Jul 2008 19:56:45 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=156</guid> <description><![CDATA[Update: i also have a complete series of posts on this which you may find interesting. The first take was pretty good, after all it got Ayende-d which is the highlight of my blogging career so far . In his post, he was pretty positive about my implementation, with one small exception: "About the only [...]]]></description> <content:encoded><![CDATA[<p>Update: i also have a complete <a
href="http://davybrion.com/blog/2009/11/requestresponse-service-layer-series/">series of posts</a> on this which you may find interesting.</p><p><a
href="http://davybrion.com/blog/2008/06/batching-wcf-calls/">The first take</a> was pretty good, after all it got <a
href="http://ayende.com/Blog/archive/2008/06/30/Batching-WCF-Calls.aspx">Ayende-d</a> which is the highlight of my blogging career so far <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . In his post, he was pretty positive about my implementation, with one small exception:</p><p><quote> "About the only thing that I would strive to improve there would be the need to explicitly register request &amp; replies. I would try to get something convention based there. Maybe something like Request<TRespose>, and then have IHandler<TRequest> and route the whole thing through the container again." </quote></p><p>Let's give that a shot <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Previously, the base implementation of the service routed the call to the correct RequestHandler like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">Response</span>[] Process(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requests)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (requests == <span
style="color: blue;">null</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">null</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> responses = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">List</span>&lt;<span
style="color: #2b91af;">Response</span>&gt;(requests.Length);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">foreach</span> (<span
style="color: blue;">var</span> request <span
style="color: blue;">in</span> requests)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Type</span> handlerType = GetHandlerTypeFor(request);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (handlerType == <span
style="color: blue;">null</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; responses.Add(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">UnsupportedRequestResponse</span>());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">continue</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">using</span> (<span
style="color: blue;">var</span> handler = GetHandlerInstance(handlerType))</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; responses.Add(handler.Handle(request));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> responses.ToArray();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">virtual</span> <span
style="color: #2b91af;">IRequestHandler</span> GetHandlerInstance(<span
style="color: #2b91af;">Type</span> handlerType)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> (<span
style="color: #2b91af;">IRequestHandler</span>)<span
style="color: #2b91af;">Container</span>.Resolve(handlerType);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: #2b91af;">Type</span> GetHandlerTypeFor(<span
style="color: #2b91af;">Request</span> request);</p></div><p></code></p><p>And then the service implementation would provide an implementation of the GetHandlerTypeFor method. In that implementation, you somehow had to map the type of the incoming Request to a handler. In the code that i posted i used a dictionary-based approach. You could've used a couple of if statements as well. The point is that you had to do that mapping which is indeed somewhat annoying.</p><p>First, we'll add a new interface on top of the IRequestHandler interface:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">interface</span> <span
style="color: #2b91af;">IRequestHandler</span> : <span
style="color: #2b91af;">IDisposable</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Response</span> Handle(<span
style="color: #2b91af;">Request</span> request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">interface</span> <span
style="color: #2b91af;">IRequestHandler</span>&lt;TRequest&gt; : <span
style="color: #2b91af;">IRequestHandler</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">where</span> TRequest : <span
style="color: #2b91af;">Request</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Response</span> Handle(TRequest request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>We also modify the base RequestHandler class to provide a derived generic class:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">RequestHandler</span> : <span
style="color: #2b91af;">Disposable</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">protected</span> <span
style="color: #2b91af;">IUnitOfWork</span> UnitOfWork { <span
style="color: blue;">get</span>; <span
style="color: blue;">private</span> <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">protected</span> RequestHandler(<span
style="color: #2b91af;">IUnitOfWork</span> unitOfWork)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; UnitOfWork = unitOfWork;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">protected</span> <span
style="color: blue;">override</span> <span
style="color: blue;">void</span> DisposeObjects()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (UnitOfWork != <span
style="color: blue;">null</span>) UnitOfWork.Dispose();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">protected</span> <span
style="color: blue;">override</span> <span
style="color: blue;">void</span> ClearReferences()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; UnitOfWork = <span
style="color: blue;">null</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">RequestHandler</span>&lt;TRequest&gt; : <span
style="color: #2b91af;">RequestHandler</span>, <span
style="color: #2b91af;">IRequestHandler</span>&lt;TRequest&gt;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">where</span> TRequest : <span
style="color: #2b91af;">Request</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">protected</span> RequestHandler(<span
style="color: #2b91af;">IUnitOfWork</span> unitOfWork) : <span
style="color: blue;">base</span>(unitOfWork) {}</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: #2b91af;">Response</span> Handle(TRequest request);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">Response</span> Handle(<span
style="color: #2b91af;">Request</span> request)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> Handle((TRequest)request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>The only reason why i still have the base RequestHandler type is to make it easier to register the RequestHandler types with the container (which i'll show below).</p><p>A specific RequestHandler can now be defined like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductCategoriesHandler</span> : <span
style="color: #2b91af;">RequestHandler</span>&lt;<span
style="color: #2b91af;">GetProductCategoriesRequest</span>&gt;</p></div><p></code></p><p>Right, now we can register all of our RequestHandler types with the container:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">void</span> RegisterRequestHandlers()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">foreach</span> (<span
style="color: blue;">var</span> type <span
style="color: blue;">in</span> <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">RequestHandler</span>).Assembly.GetTypes())</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (type.IsSubclassOf(<span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">RequestHandler</span>)) &amp;&amp; type.BaseType.IsGenericType)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> serviceType = <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">IRequestHandler</span>&lt;&gt;).MakeGenericType(type.BaseType.GetGenericArguments());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Register(<span
style="color: #2b91af;">Component</span>.For(serviceType).ImplementedBy(type).LifeStyle.Transient);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>So now each generic RequestHandler type is registered through the generic IRequestHandler type.</p><p>Our base Service implementation now looks like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">Response</span>[] Process(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requests)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (requests == <span
style="color: blue;">null</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">null</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> responses = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">List</span>&lt;<span
style="color: #2b91af;">Response</span>&gt;(requests.Length);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">foreach</span> (<span
style="color: blue;">var</span> request <span
style="color: blue;">in</span> requests)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Type</span> handlerType = <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">IRequestHandler</span>&lt;&gt;).MakeGenericType(request.GetType());</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">using</span> (<span
style="color: blue;">var</span> handler = (<span
style="color: #2b91af;">IRequestHandler</span>)<span
style="color: #2b91af;">Container</span>.Resolve(handlerType))</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; responses.Add(handler.Handle(request));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> responses.ToArray();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>And now you no longer need to map the Request type to the RequestHandler type yourself since the container now takes care of that for us.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F07%2Fbatching-wcf-calls-take-2%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/07/batching-wcf-calls-take-2/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/07/batching-wcf-calls-take-2/"  data-text="Batching WCF calls, Take 2" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/07/batching-wcf-calls-take-2/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/07/batching-wcf-calls-take-2/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/07/batching-wcf-calls-take-2/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>The Service Call Batcher</title><link>http://davybrion.com/blog/2008/06/the-service-call-batcher/</link> <comments>http://davybrion.com/blog/2008/06/the-service-call-batcher/#comments</comments> <pubDate>Sat, 28 Jun 2008 07:30:25 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=154</guid> <description><![CDATA[Picking up where we left off with the WCF batching... We had the following code client-side to execute a few service methods with one request: &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; var results = service.Process(new GetProductCategoriesRequest(), new GetProductOverviewsRequest()); &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; View.ProductCategories = ((GetProductCategoriesResponse)results[0]).ProductCategories; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; View.Products = ((GetProductOverviewsResponse)results[1]).Products; Similar to my query batcher, i wrote this [...]]]></description> <content:encoded><![CDATA[<p>Picking up where we left off with <a
href="http://davybrion.com/blog/2008/06/batching-wcf-calls/">the WCF batching</a>... We had the following code client-side to execute a few service methods with one request:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> results = service.Process(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductCategoriesRequest</span>(), <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductOverviewsRequest</span>());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.ProductCategories = ((<span
style="color: #2b91af;">GetProductCategoriesResponse</span>)results[0]).ProductCategories;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.Products = ((<span
style="color: #2b91af;">GetProductOverviewsResponse</span>)results[1]).Products;</p></div><p></code></p><p>Similar to my <a
href="http://davybrion.com/blog/2008/06/the-query-batcher/">query batcher</a>, i wrote this simple WCFCallBatcher class:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">ServiceCallBatcher</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">readonly</span> <span
style="color: #2b91af;">IService</span> service;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">readonly</span> <span
style="color: #2b91af;">Dictionary</span>&lt;<span
style="color: blue;">string</span>, <span
style="color: blue;">int</span>&gt; responsePositions = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">Dictionary</span>&lt;<span
style="color: blue;">string</span>, <span
style="color: blue;">int</span>&gt;();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">readonly</span> <span
style="color: #2b91af;">List</span>&lt;<span
style="color: #2b91af;">Request</span>&gt; requests = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">List</span>&lt;<span
style="color: #2b91af;">Request</span>&gt;();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: #2b91af;">Response</span>[] responses;</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> ServiceCallBatcher(<span
style="color: #2b91af;">IService</span> service)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">this</span>.service = service;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> Add(<span
style="color: blue;">string</span> key, <span
style="color: #2b91af;">Request</span> request)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; requests.Add(request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; responsePositions.Add(key, requests.Count - 1);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> T Get&lt;T&gt;(<span
style="color: blue;">string</span> key) <span
style="color: blue;">where</span> T : <span
style="color: #2b91af;">Response</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (responses == <span
style="color: blue;">null</span>) ExecuteRequests();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> (T)responses[responsePositions[key]];</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">void</span> ExecuteRequests()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; responses = service.Process(requests.ToArray());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>and now we can rewrite the client code like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> batcher = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">ServiceCallBatcher</span>(service);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; batcher.Add(<span
style="color: #a31515;">"categories"</span>, <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductCategoriesRequest</span>());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; batcher.Add(<span
style="color: #a31515;">"products"</span>, <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductOverviewsRequest</span>());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.ProductCategories = batcher.Get&lt;<span
style="color: #2b91af;">GetProductCategoriesResponse</span>&gt;(<span
style="color: #a31515;">"categories"</span>).ProductCategories;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.Products = batcher.Get&lt;<span
style="color: #2b91af;">GetProductOverviewsResponse</span>&gt;(<span
style="color: #a31515;">"products"</span>).Products;</p></div><p></code></p><p>Yes, we've got more lines of code now, but i like this block of a code a lot more than the earlier one. This is much more readable.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F06%2Fthe-service-call-batcher%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/06/the-service-call-batcher/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/06/the-service-call-batcher/"  data-text="The Service Call Batcher" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/06/the-service-call-batcher/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/06/the-service-call-batcher/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/06/the-service-call-batcher/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Batching WCF calls</title><link>http://davybrion.com/blog/2008/06/batching-wcf-calls/</link> <comments>http://davybrion.com/blog/2008/06/batching-wcf-calls/#comments</comments> <pubDate>Thu, 26 Jun 2008 14:13:49 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=153</guid> <description><![CDATA[Update: i also have a complete series of posts on this which you may find interesting. What happens if you have the following code client-side: &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; View.ProductCategories = service.GetProductCategories(); &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; View.Products = service.GetProductOverviews(); The service variable is a reference to a WCF service proxy. This means that this causes 2 remote [...]]]></description> <content:encoded><![CDATA[<p>Update: i also have a complete <a
href="http://davybrion.com/blog/2009/11/requestresponse-service-layer-series/">series of posts</a> on this which you may find interesting.</p><p>What happens if you have the following code client-side:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.ProductCategories = service.GetProductCategories();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.Products = service.GetProductOverviews();</p></div><p></code></p><p>The service variable is a reference to a WCF service proxy. This means that this causes 2 remote service calls. I really hate unnecessary/excessive roundtrips, so i would rather retrieve this data from the service in one roundtrip.  Unfortunately, this is not something that is supported by WCF out of the box, so if you want to do this you have to do it yourself.  There are a couple of options, so i started browsing the web. Once again, it's <a
href="http://www.ayende.com/Blog/archive/2008/03/07/SOA-Future-Batches.aspx">Ayende to the rescue</a>.  The approach he suggests is a bit cumbersome compared to how you'd normally design your services, but it does offer a great deal of flexibility and it allows you to nicely batch your requests.  So i figured i should try implementing this approach.</p><p>The idea is to provide a service method that looks like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Response</span>[] Process(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requests);</p></div><p></code></p><p>Each Request corresponds to what used to be a normal service method, and this method returns a Response for each Request.  In Ayende's post, he suggest offering this as the only service method. I won't go that far though. I'll offer this method, and each 'normal' method allthough those methods will also use Request types as input variables and Response types as return values.  The idea is to be able to use each service method individually, or to have multiple service methods executed in one roundtrip through the Process method.</p><p>We need a way to define Requests and Responses, so we create the following classes:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">Response</span> { }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">Request</span> {}</p></div><p></code></p><p>For now, these are empty but i'm pretty sure i'll add a few members to these later on. Then we define specific Request and Response types for the functionality our service needs to offer:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductCategoriesRequest</span> : <span
style="color: #2b91af;">Request</span> {}</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductOverviewsRequest</span> : <span
style="color: #2b91af;">Request</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">int</span>? ProductCategoryId { <span
style="color: blue;">get</span>; <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p><br
/></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductCategoriesResponse</span> : <span
style="color: #2b91af;">Response</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">ProductCategoryDTO</span>[] ProductCategories { <span
style="color: blue;">get</span>; <span
style="color: blue;">private</span> <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> GetProductCategoriesResponse(<span
style="color: #2b91af;">ProductCategoryDTO</span>[] productCategories)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ProductCategories = productCategories;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductOverviewsResponse</span> : <span
style="color: #2b91af;">Response</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">ProductOverviewDTO</span>[] Products { <span
style="color: blue;">get</span>; <span
style="color: blue;">private</span> <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> GetProductOverviewsResponse(<span
style="color: #2b91af;">ProductOverviewDTO</span>[] products)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Products = products;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>We then create a base interface that each service will implement (along with more specific service interfaces):</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ServiceContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">interface</span> <span
style="color: #2b91af;">IService</span> : <span
style="color: #2b91af;">IDisposable</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;summary&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> Processes each request within the same service call</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;/summary&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;param name="requests"&gt;</span><span
style="color: green;">each request</span><span
style="color: gray;">&lt;/param&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;returns&gt;</span><span
style="color: green;">the corresponding responses</span><span
style="color: gray;">&lt;/returns&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">OperationContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ServiceKnownType</span>(<span
style="color: #a31515;">"GetKnownTypes"</span>, <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">KnownTypeProvider</span>))]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Response</span>[] Process(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requests);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>The KnownTypeProvider is responsible for providing a list of types that should be treated as KnownTypes during serialization/deserialization. We could also list each type that derives from Response/Request but that will become a long list, so i went for this approach.  The code of the KnownTypeProvider class looks like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">static</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">KnownTypeProvider</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">readonly</span> <span
style="color: #2b91af;">List</span>&lt;<span
style="color: #2b91af;">Type</span>&gt; knownTypes;</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">static</span> KnownTypeProvider()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; knownTypes = BuildListOfKnownTypes();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: #2b91af;">List</span>&lt;<span
style="color: #2b91af;">Type</span>&gt; BuildListOfKnownTypes()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Assembly</span> containingAssembly = <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">KnownTypeProvider</span>).Assembly;</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> containingAssembly.GetTypes()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .Select(t =&gt; t)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .Where(t =&gt; t.IsSubclassOf(<span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">Request</span>)) || t.IsSubclassOf(<span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">Response</span>)))</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .ToList();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">static</span> <span
style="color: #2b91af;">IEnumerable</span>&lt;<span
style="color: #2b91af;">Type</span>&gt; GetKnownTypes(<span
style="color: #2b91af;">ICustomAttributeProvider</span> provider)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> knownTypes;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>Our real service now looks like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ServiceContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">interface</span> <span
style="color: #2b91af;">IProductsService</span> : <span
style="color: #2b91af;">IService</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">OperationContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">GetProductCategoriesResponse</span> GetProductCategories(<span
style="color: #2b91af;">GetProductCategoriesRequest</span> request);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">OperationContract</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">GetProductOverviewsResponse</span> GetProductOverviews(<span
style="color: #2b91af;">GetProductOverviewsRequest</span> request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>To handle these requests, i came up with the following RequestHandler type:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">RequestHandler</span> : <span
style="color: #2b91af;">Disposable</span>, <span
style="color: #2b91af;">IRequestHandler</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">IUnitOfWork</span> UnitOfWork { <span
style="color: blue;">get</span>; <span
style="color: blue;">private</span> <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">protected</span> RequestHandler(<span
style="color: #2b91af;">IUnitOfWork</span> unitOfWork)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; UnitOfWork = unitOfWork;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">protected</span> <span
style="color: blue;">override</span> <span
style="color: blue;">void</span> DisposeObjects()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (UnitOfWork != <span
style="color: blue;">null</span>) UnitOfWork.Dispose();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">protected</span> <span
style="color: blue;">override</span> <span
style="color: blue;">void</span> ClearReferences()</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; UnitOfWork = <span
style="color: blue;">null</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: #2b91af;">Response</span> Handle(<span
style="color: #2b91af;">Request</span> request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>And the implementation of one of these concrete RequestHandlers looks like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">GetProductOverviewsHandler</span> : <span
style="color: #2b91af;">RequestHandler</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">ProductRepository</span> ProductRepository { <span
style="color: blue;">get</span>; <span
style="color: blue;">private</span> <span
style="color: blue;">set</span>; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> GetProductOverviewsHandler(<span
style="color: #2b91af;">IUnitOfWork</span> unitOfWork, <span
style="color: #2b91af;">ProductRepository</span> productRepository)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; : <span
style="color: blue;">base</span>(unitOfWork)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ProductRepository = productRepository;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: #2b91af;">Response</span> Handle(<span
style="color: #2b91af;">Request</span> request)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> typedRequest = (<span
style="color: #2b91af;">GetProductOverviewsRequest</span>)request;</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (typedRequest.ProductCategoryId.HasValue)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> fetchStrategy = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FetchStrategy</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; { Association = <span
style="color: #a31515;">"Supplier"</span>, FetchMode = <span
style="color: #2b91af;">FetchMode</span>.Join };</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> productOverviews = ProductRepository.FindAllByCategory(</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; typedRequest.ProductCategoryId.Value, fetchStrategy);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductOverviewsResponse</span>(productOverviews.ToOverviewDTOs());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">else</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: green;">// TODO: use query batcher to fetch all suppliers and products in one trip</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> productOverviews = ProductRepository.FindAll();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductOverviewsResponse</span>(productOverviews.ToOverviewDTOs());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>Now we have to make sure we can actually use this RequestHandlers in a generic manner.  I came up with the following base class for my services:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">Service</span> : <span
style="color: #2b91af;">IService</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;summary&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> server-side service implementation should be stateless, but the IService</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> interface defines the Dispose method, so we just provide an empty one here</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: gray;">///</span><span
style="color: green;"> </span><span
style="color: gray;">&lt;/summary&gt;</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> Dispose() {}</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">Response</span>[] Process(<span
style="color: blue;">params</span> <span
style="color: #2b91af;">Request</span>[] requests)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (requests == <span
style="color: blue;">null</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">null</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> responses = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">List</span>&lt;<span
style="color: #2b91af;">Response</span>&gt;(requests.Length);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">foreach</span> (<span
style="color: blue;">var</span> request <span
style="color: blue;">in</span> requests)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Type</span> handlerType = GetHandlerTypeFor(request);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (handlerType == <span
style="color: blue;">null</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; responses.Add(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">UnsupportedRequestResponse</span>());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">continue</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">using</span> (<span
style="color: blue;">var</span> handler = GetHandlerInstance(handlerType))</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; responses.Add(handler.Handle(request));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> responses.ToArray();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">virtual</span> <span
style="color: #2b91af;">IRequestHandler</span> GetHandlerInstance(<span
style="color: #2b91af;">Type</span> handlerType)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> (<span
style="color: #2b91af;">IRequestHandler</span>)<span
style="color: #2b91af;">Container</span>.Resolve(handlerType);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">abstract</span> <span
style="color: #2b91af;">Type</span> GetHandlerTypeFor(<span
style="color: #2b91af;">Request</span> request);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>And the real service then looks like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">ProductsService</span> : <span
style="color: #2b91af;">Service</span>, <span
style="color: #2b91af;">IProductsService</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">readonly</span> <span
style="color: blue;">object</span> monitor = <span
style="color: blue;">new</span> <span
style="color: blue;">object</span>();</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">readonly</span> <span
style="color: #2b91af;">Dictionary</span>&lt;<span
style="color: #2b91af;">Type</span>, <span
style="color: #2b91af;">Type</span>&gt; requestTypesToRequestHandlerTypes</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">Dictionary</span>&lt;<span
style="color: #2b91af;">Type</span>, <span
style="color: #2b91af;">Type</span>&gt;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; { <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">GetProductCategoriesRequest</span>), <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">GetProductCategoriesHandler</span>) },</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; { <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">GetProductOverviewsRequest</span>), <span
style="color: blue;">typeof</span>(<span
style="color: #2b91af;">GetProductOverviewsHandler</span>) }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; };</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">GetProductCategoriesResponse</span> GetProductCategories(<span
style="color: #2b91af;">GetProductCategoriesRequest</span> request)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> (<span
style="color: #2b91af;">GetProductCategoriesResponse</span>)Process(request)[0];</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: #2b91af;">GetProductOverviewsResponse</span> GetProductOverviews(<span
style="color: #2b91af;">GetProductOverviewsRequest</span> request)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> (<span
style="color: #2b91af;">GetProductOverviewsResponse</span>)Process(request)[0];</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: #2b91af;">Type</span> GetHandlerTypeFor(<span
style="color: #2b91af;">Request</span> request)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Type</span> requestType = request.GetType();</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">lock</span> (monitor)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (!requestTypesToRequestHandlerTypes.ContainsKey(requestType))</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">null</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> requestTypesToRequestHandlerTypes[requestType];</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>At this point, using a dictionary to map the Request types to the RequestHandler types seems silly, but this is just a small part of the service, more methods will be added so more Request and RequestHandlers will be handled, and in that case i prefer to use a dictionary lookup over a big if statement <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>So now i can do this client-side:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> results = service.Process(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductCategoriesRequest</span>(), <span
style="color: blue;">new</span> <span
style="color: #2b91af;">GetProductOverviewsRequest</span>());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.ProductCategories = ((<span
style="color: #2b91af;">GetProductCategoriesResponse</span>)results[0]).ProductCategories;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; View.Products = ((<span
style="color: #2b91af;">GetProductOverviewsResponse</span>)results[1]).Products;</p></div><p></code></p><p>And it only uses one remote call which will be much better for performance.  At this point, the syntax is not so nice, but i'll probably provide something similar to my <a
href="http://davybrion.com/blog/2008/06/the-query-batcher/">query batcher class</a> so that should improve readability.</p><p>So that's pretty much it... it takes some effort to set this up, and there's still more to be done (dealing with exceptions in one of the requests for instance) but once you've got it set up, i kinda like it. Sure, implementing service methods takes more code than it used to because of the extra classes involved, but they do offer a few very important benefits.  You may have noticed that the RequestHandler types receive all of their dependencies through the constructor, and that they are created through the IoC container.  This means i can very easily add/remove/change dependencies in my handlers without having to modify code in other places.  It also means i can test my service implementations in a thorough manner while providing mocked dependencies instead of the real ones.  Another big advantage is that i can add optional parameters to my Request types and thus, offer more functionality through my RequestHandlers without having to update the services and the proxies.</p><p>So all in all, while this approach requires to you write more code at first, i think it might actually end up giving you more flexibility for changes later on, while offering you much more control over certain performance characteristics.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F06%2Fbatching-wcf-calls%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/06/batching-wcf-calls/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/06/batching-wcf-calls/"  data-text="Batching WCF calls" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/06/batching-wcf-calls/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/06/batching-wcf-calls/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/06/batching-wcf-calls/feed/</wfw:commentRss> <slash:comments>16</slash:comments> </item> <item><title>WCF Exception Handling with PostSharp</title><link>http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/</link> <comments>http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/#comments</comments> <pubDate>Fri, 23 May 2008 09:37:55 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Aspect Oriented Programming]]></category> <category><![CDATA[PostSharp]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=120</guid> <description><![CDATA[In your WCF service methods, you should always provide proper exception handling. The exception handling code is almost always the same, so it's usually just copy/pasted in each method. Here's an example of a typical service method: &#160;&#160;&#160; &#160;&#160;&#160; public void PersistOrder(Order order) &#160;&#160;&#160; &#160;&#160;&#160; { &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; try &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; { &#160;&#160;&#160; [...]]]></description> <content:encoded><![CDATA[<p>In your WCF service methods, you should always provide proper exception handling. The exception handling code is almost always the same, so it's usually just copy/pasted in each method. Here's an example of a typical service method:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> PersistOrder(<span
style="color: #2b91af;">Order</span> order)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">try</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Container</span>.Resolve&lt;<span
style="color: #2b91af;">IPersistOrderHandler</span>&gt;().Handle(order);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">catch</span> (<span
style="color: #2b91af;">BusinessException</span> b)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultException</span>&lt;<span
style="color: #2b91af;">BusinessExceptionInformation</span>&gt;(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">BusinessExceptionInformation</span>(b),</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultReason</span>(b.Message));&nbsp;&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">catch</span> (<span
style="color: #2b91af;">FaultException</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">catch</span> (<span
style="color: #2b91af;">Exception</span> e)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Container</span>.Resolve&lt;<span
style="color: #2b91af;">ILogger</span>&gt;().LogException(e);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultException</span>(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultReason</span>(e.Message));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>That's a lot of code, even though only ONE line will differ from the other service methods in this service.  Let's clean up this mess, shall we? Exception handling is a <a
href="http://en.wikipedia.org/wiki/Cross-cutting_concern">cross cutting concern</a> so we might as well put it in one place (at least, one place for each different kind of exception handling that you need).  We'll use PostSharp to define an ApplyServiceExceptionHandling aspect:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">ApplyServiceExceptionHandling</span> : <span
style="color: #2b91af;">OnExceptionAspect</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: blue;">void</span> OnException(<span
style="color: #2b91af;">MethodExecutionEventArgs</span> eventArgs)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (eventArgs.Exception <span
style="color: blue;">is</span> <span
style="color: #2b91af;">BusinessException</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultException</span>&lt;<span
style="color: #2b91af;">BusinessExceptionInformation</span>&gt;(</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">new</span> <span
style="color: #2b91af;">BusinessExceptionInformation</span>(eventArgs.Exception <span
style="color: blue;">as</span> <span
style="color: #2b91af;">BusinessException</span>),</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultReason</span>(eventArgs.Exception.Message));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">else</span> <span
style="color: blue;">if</span> (eventArgs.Exception <span
style="color: blue;">is</span> <span
style="color: #2b91af;">FaultException</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; eventArgs.FlowBehavior = <span
style="color: #2b91af;">FlowBehavior</span>.RethrowException;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">else</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Container</span>.Resolve&lt;<span
style="color: #2b91af;">ILogger</span>&gt;().LogException(eventArgs.Exception);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultException</span>(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultReason</span>(eventArgs.Exception.Message));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>And now we can modify the earlier service method to this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ApplyServiceExceptionHandling</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> PersistOrder(<span
style="color: #2b91af;">Order</span> order)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Container</span>.Resolve&lt;<span
style="color: #2b91af;">IPersistOrderHandler</span>&gt;().Handle(order);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>That's a lot cleaner than the previous version right? Actually, this service has more than one service method so we're better off moving the ApplyServiceExceptionHandling attribute to the class level instead of the method level:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ApplyServiceExceptionHandling</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">OrderManagementService</span> : <span
style="color: #2b91af;">IOrderManagementService</span></p></div><p></code></p><p>now we can get rid of all of the exception handling code in each service method, but each one will have exception handling applied to it because the exception handling aspect is applied to the class, and thus, to each method of that class.  And if you need to modify your exception handling (to handle TargetInvocationExceptions with BusinessExceptions as InnerExceptions for instance?) you'd only have to do this in one place.</p><p>Btw, i'm aware of WCF's IErrorHandler interface (which allows you to handle exceptions in a general manner as well)... i just don't like it <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F05%2Fwcf-exception-handling-with-postsharp%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/"  data-text="WCF Exception Handling with PostSharp" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Sending NHibernate entities over the WCF wire</title><link>http://davybrion.com/blog/2008/01/sending-nhibernate-entities-over-the-wcf-wire/</link> <comments>http://davybrion.com/blog/2008/01/sending-nhibernate-entities-over-the-wcf-wire/#comments</comments> <pubDate>Thu, 03 Jan 2008 14:12:51 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://ralinx.wordpress.com/2008/01/03/sending-nhibernate-entities-over-the-wcf-wire/</guid> <description><![CDATA[Note: i no longer recommend this solution for reasons that i've talked about in more detail here. Last year, Tim Scott posted this very good article on how to distribute NHiberate entities through WCF services. In it, he mentions this: We should mention that this application uses NHibernate 1.02. As of this writing, NHibernate has [...]]]></description> <content:encoded><![CDATA[<p>Note: i no longer recommend this solution for reasons that i've talked about in more detail <a
href="http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/">here</a>.</p><p>Last year, Tim Scott posted <a
href="http://lunaverse.wordpress.com/2007/05/09/remoting-using-wcf-and-nhibernate/"> this very good article on how to distribute NHiberate entities through WCF services</a>. In it, he mentions this:</p><blockquote>We should mention that this application uses NHibernate 1.02. As of this writing, NHibernate has released version 1.2. We tested the application with NHibernate 1.2 before changing to the NetDataContractSerializer, and verified that it exhibits the same problem. We have not verified that the solution described here will work with NHibnerate 1.2, although we expect it will.</blockquote><p>I created a small sample that uses his solution with NHibernate 1.2 and my Northwind example and in this post, we'll walk through the sample.  But first, a little bit of background information.  By default, WCF services use the DataContractSerializer to serialize/deserialize types. But when you're using NHibernate, you're most likely using some of the persistent collection types and proxies. Some people just want to use the same types serverside and clientside. For instance, retrieving a Customer object with his Orders collection through a service, manipulating one of the Order objects clientside, perhaps remove an order from the collection, send the object graph back to the server, attach it to an nhibernate session, persist the whole thing and be done with it. I'm still somewhat undecided as to whether or not this is a good way of doing things but that's beside the point of this post. Default WCF services do not make this possible but you can make it work rather easily.  WCF includes the NetDataContractSerializer which differs from the normal DataContractSerializer in that it includes CLR type information in the serialized data. This makes the above scenario possible.  You do lose all interoperability with other platforms, and your clients need the same types you use server side.</p><p>First of all, this is the service contract:</p><div
style="font-family:Consolas;font-size:10pt;color:black;background:white;"><p
style="margin:0;">&nbsp;&nbsp;&nbsp; [<span
style="color:#2b91af;">ServiceContract</span>]</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; <span
style="color:blue;">public</span> <span
style="color:blue;">interface</span> <span
style="color:#2b91af;">ICustomerService</span></p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color:#2b91af;">UseNetDataContractSerializer</span>]</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color:#2b91af;">OperationContract</span>]</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:#2b91af;">IList</span>&lt;<span
style="color:#2b91af;">Customer</span>&gt; GetCustomersWithTheirOrders();</p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color:#2b91af;">UseNetDataContractSerializer</span>]</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color:#2b91af;">OperationContract</span>]</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">void</span> PersistCustomer(<span
style="color:#2b91af;">Customer</span> customer);</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; }</p></div><p>The [UseNetDataContractSerializer] is not a standard WCF attribute, but is a part of Tim Scott's solution. You can find the implementation of the attribute in his post, or in my code which you can download at the bottom of this post. It basically comes down to this: the serialization behavior of operations decorated with this attribute is modified to use the NetDataContractSerializer instead of the default DataContractSerializer.</p><p>The implementation of the service contract looks like this:</p><div
style="font-family:Consolas;font-size:10pt;color:black;background:white;"><p
style="margin:0;">&nbsp;&nbsp;&nbsp; <span
style="color:blue;">public</span> <span
style="color:blue;">class</span> <span
style="color:#2b91af;">CustomerService</span> : <span
style="color:#2b91af;">ICustomerService</span></p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">private</span> <span
style="color:blue;">static</span> <span
style="color:blue;">readonly</span> <span
style="color:#2b91af;">ISessionFactory</span> _sessionFactory;</p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">static</span> CustomerService()</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">try</span></p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:#2b91af;">Configuration</span> configuration = <span
style="color:blue;">new</span> <span
style="color:#2b91af;">Configuration</span>().AddAssembly(<span
style="color:#a31515;">"Northwind.Domain"</span>);</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _sessionFactory = configuration.BuildSessionFactory();</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">catch</span> (<span
style="color:#2b91af;">Exception</span> e)</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:#2b91af;">Console</span>.Write(e);</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">throw</span>;</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">public</span> <span
style="color:#2b91af;">IList</span>&lt;<span
style="color:#2b91af;">Customer</span>&gt; GetCustomersWithTheirOrders()</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">using</span> (<span
style="color:#2b91af;">ISession</span> session = _sessionFactory.OpenSession())</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">return</span> session.CreateCriteria(<span
style="color:blue;">typeof</span>(<span
style="color:#2b91af;">Customer</span>))</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .SetFetchMode(<span
style="color:#a31515;">"Orders"</span>, <span
style="color:#2b91af;">FetchMode</span>.Join)</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .SetResultTransformer(<span
style="color:#2b91af;">CriteriaUtil</span>.DistinctRootEntity)</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .List&lt;<span
style="color:#2b91af;">Customer</span>&gt;();</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">public</span> <span
style="color:blue;">void</span> PersistCustomer(<span
style="color:#2b91af;">Customer</span> customer)</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">using</span> (<span
style="color:#2b91af;">ISession</span> session = _sessionFactory.OpenSession())</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">using</span> (<span
style="color:#2b91af;">ITransaction</span> transaction = session.BeginTransaction())</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; session.SaveOrUpdate(customer);</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; session.Flush();</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; transaction.Commit();</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; }</p></div><p>First of all, this is just an example, that's why the ISessionFactory is created within the service implementation, in a real system i wouldn't do this.  Anyway, the GetCustomersWithTheirOrders method returns a list of all Customers, with their Orders.  An Order contains references to an Employee and a Shipper.  The Employee and Shipper will not be retrieved from the database, but NHibernate will initialize them with proxy objects to enable lazy-loading.  Obviously, the lazy-loading won't work once you're outside of the scope of the NHibernate session, but it's important to note that there will be proxies in our object graph.</p><p>At first i had decorated my entity classes with the [DataContract] and [DataMember] attributes but that really messed up the deserialization of the proxies. Now my Entity classes are only decorated with the [Serializable] attribute. NetDataContractSerializer should work in both cases, but i only got it working properly when they were [Serializable].</p><p>Right, so now we have the service contract and the implementation, it's time to host it. My solution contains an example of a console host as well as a service hosted in IIS. For this post, i'll just go over the console host and console client. You can find the IIS example (which is practically identical anyway) in the downloadable solution.</p><p>So, in the console host project, i have the following in my app.config file:</p><div
style="font-family:Consolas;font-size:10pt;color:black;background:white;"><p
style="margin:0;"><span
style="color:blue;">&nbsp; &lt;</span><span
style="color:#a31515;">system.serviceModel</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">services</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">service</span><span
style="color:blue;"> </span><span
style="color:red;">name</span><span
style="color:blue;">=</span>"<span
style="color:blue;">ServiceImplementation.CustomerService</span>"<span
style="color:blue;"> </span><span
style="color:red;">behaviorConfiguration</span><span
style="color:blue;">=</span>"<span
style="color:blue;">customerServiceBehavior</span>"<span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">endpoint</span><span
style="color:blue;"> </span><span
style="color:red;">contract</span><span
style="color:blue;">=</span>"<span
style="color:blue;">ServiceInterface.ICustomerService</span>"<span
style="color:blue;"> </span><span
style="color:red;">binding</span><span
style="color:blue;">=</span>"<span
style="color:blue;">wsHttpBinding</span>"<span
style="color:blue;"> </span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span
style="color:red;">bindingConfiguration</span><span
style="color:blue;">=</span>"<span
style="color:blue;">customerServiceBinding</span>"<span
style="color:blue;"> /&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">endpoint</span><span
style="color:blue;"> </span><span
style="color:red;">contract</span><span
style="color:blue;">=</span>"<span
style="color:blue;">IMetadataExchange</span>"<span
style="color:blue;"> </span><span
style="color:red;">binding</span><span
style="color:blue;">=</span>"<span
style="color:blue;">mexHttpBinding</span>"<span
style="color:blue;"> </span><span
style="color:red;">address</span><span
style="color:blue;">=</span>"<span
style="color:blue;">mex</span>"<span
style="color:blue;"> /&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">host</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">baseAddresses</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">add</span><span
style="color:blue;"> </span><span
style="color:red;">baseAddress</span><span
style="color:blue;">=</span>"<span
style="color:blue;">http://localhost:8000/CustomerService</span>"<span
style="color:blue;">/&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">baseAddresses</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">host</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">service</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">services</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">bindings</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">wsHttpBinding</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">binding</span><span
style="color:blue;"> </span><span
style="color:red;">name</span><span
style="color:blue;">=</span>"<span
style="color:blue;">customerServiceBinding</span>"<span
style="color:blue;"> </span><span
style="color:red;">maxReceivedMessageSize</span><span
style="color:blue;">=</span>"<span
style="color:blue;">2147483647</span>"<span
style="color:blue;"> /&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">wsHttpBinding</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">bindings</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">behaviors</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">serviceBehaviors</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">behavior</span><span
style="color:blue;"> </span><span
style="color:red;">name</span><span
style="color:blue;">=</span>"<span
style="color:blue;">customerServiceBehavior</span>"<span
style="color:blue;"> &gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">serviceMetadata</span><span
style="color:blue;"> </span><span
style="color:red;">httpGetEnabled</span><span
style="color:blue;">=</span>"<span
style="color:blue;">true</span>"<span
style="color:blue;"> </span><span
style="color:red;">httpGetUrl</span><span
style="color:blue;">=</span>""<span
style="color:blue;">/&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">behavior</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">serviceBehaviors</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">behaviors</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &lt;/</span><span
style="color:#a31515;">system.serviceModel</span><span
style="color:blue;">&gt;</span></p></div><p>The service is then started like this:</p><div
style="font-family:Consolas;font-size:10pt;color:black;background:white;"><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">private</span> <span
style="color:blue;">static</span> <span
style="color:blue;">void</span> Main(<span
style="color:blue;">string</span>[] args)</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">using</span> (<span
style="color:#2b91af;">ServiceHost</span> host = <span
style="color:blue;">new</span> <span
style="color:#2b91af;">ServiceHost</span>(<span
style="color:blue;">typeof</span>(<span
style="color:#2b91af;">CustomerService</span>)))</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; host.Open();</p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:#2b91af;">Console</span>.WriteLine(<span
style="color:#a31515;">"press ENTER to quit"</span>);</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:#2b91af;">Console</span>.ReadLine();</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p>As you can see, nothing special here... it's pretty much your typical self-hosting WCF example.  Except that the maximum message size has been increased since we'll be sending large object graphs over the wire.</p><p>The client configuration looks like this:</p><div
style="font-family:Consolas;font-size:10pt;color:black;background:white;"><p
style="margin:0;"><span
style="color:blue;">&nbsp; &lt;</span><span
style="color:#a31515;">system.serviceModel</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">bindings</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">wsHttpBinding</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">binding</span><span
style="color:blue;"> </span><span
style="color:red;">name</span><span
style="color:blue;">=</span>"<span
style="color:blue;">customerServiceBinding</span>"<span
style="color:blue;"> </span><span
style="color:red;">maxReceivedMessageSize</span><span
style="color:blue;">=</span>"<span
style="color:blue;">2147483647</span>"<span
style="color:blue;"> /&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">wsHttpBinding</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">bindings</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">client</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span
style="color:#a31515;">endpoint</span><span
style="color:blue;"> </span><span
style="color:red;">address</span><span
style="color:blue;">=</span>"<span
style="color:blue;">http://localhost:8000/CustomerService</span>"<span
style="color:blue;"> </span><span
style="color:red;">binding</span><span
style="color:blue;">=</span>"<span
style="color:blue;">wsHttpBinding</span>"<span
style="color:blue;"> </span><span
style="color:red;">name</span><span
style="color:blue;">=</span>"<span
style="color:blue;">CustomerServiceEndPoint</span>"</p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span
style="color:red;">bindingConfiguration</span><span
style="color:blue;">=</span>"<span
style="color:blue;">customerServiceBinding</span>"<span
style="color:blue;"> </span><span
style="color:red;">contract</span><span
style="color:blue;">=</span>"<span
style="color:blue;">ServiceInterface.ICustomerService</span>"<span
style="color:blue;"> /&gt;</span></p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &nbsp; &lt;/</span><span
style="color:#a31515;">client</span><span
style="color:blue;">&gt;</span></p><p
style="margin:0;">&nbsp;</p><p
style="margin:0;"><span
style="color:blue;">&nbsp; &lt;/</span><span
style="color:#a31515;">system.serviceModel</span><span
style="color:blue;">&gt;</span></p></div><p>And the client uses the service like this:</p><div
style="font-family:Consolas;font-size:10pt;color:black;background:white;"><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:blue;">private</span> <span
style="color:blue;">static</span> <span
style="color:blue;">void</span> Main(<span
style="color:blue;">string</span>[] args)</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:#2b91af;">ChannelFactory</span>&lt;<span
style="color:#2b91af;">ICustomerService</span>&gt; factory = <span
style="color:blue;">new</span> <span
style="color:#2b91af;">ChannelFactory</span>&lt;<span
style="color:#2b91af;">ICustomerService</span>&gt;(<span
style="color:#a31515;">"CustomerServiceEndPoint"</span>);</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:#2b91af;">ICustomerService</span> proxy = factory.CreateChannel();</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color:#2b91af;">IList</span>&lt;<span
style="color:#2b91af;">Customer</span>&gt; customers = proxy.GetCustomersWithTheirOrders();</p><p
style="margin:0;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p>I didn't write a test for this to prove it works, but if you step through it and you explore the returned object graph using the debugger, you'll see that everything is of the correct type... even the proxies make it through correctly. Manipulating the graph and using the PersistCustomer method also works, but it's not in this example anymore because i didn't wanna pollute my database every time i ran it to test it.</p><p>I did have problems when i was hosting the service both in the console and through IIS at the same time... some requests would then fail to deserialize the returned graph properly. If you don't run both hosts at the same time, it works.  I have no idea why this caused issues, but after wasting a few hours trying to figure it out, i just gave up.  You can reproduce it by running the ServiceConsoleHost, ServiceClient and ServiceWebClient projects in the solution.  Sometimes that just works as well, so you may have to try a few times to get it to fail. So if anyone can shed some light on that issue, i'd be most interested in hearing about it <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>You can download the solution <a
href="http://davybrion.com/NHibernateAndWcfExample.zip">here</a>.  Note that this is a Visual Studio 2008 solution...</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F01%2Fsending-nhibernate-entities-over-the-wcf-wire%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/01/sending-nhibernate-entities-over-the-wcf-wire/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/01/sending-nhibernate-entities-over-the-wcf-wire/"  data-text="Sending NHibernate entities over the WCF wire" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/01/sending-nhibernate-entities-over-the-wcf-wire/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/01/sending-nhibernate-entities-over-the-wcf-wire/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/01/sending-nhibernate-entities-over-the-wcf-wire/feed/</wfw:commentRss> <slash:comments>38</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 2/99 queries in 0.060 seconds using disk: basic
Object Caching 1612/1817 objects using disk: basic
Content Delivery Network via Amazon Web Services: CloudFront: d18sni7re4ly7f.cloudfront.net

Served from: davybrion.com @ 2012-02-08 04:51:50 -->
