<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;AkMHRX8ycCp7ImA9WxRRFU0.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705</id><updated>2008-09-27T11:40:34.198+02:00</updated><title>Javi's technical blog</title><subtitle type="html">Random thoughts on .NET and other technologies</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://javicrespotech.blogspot.com/" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/JavisTechnicalBlog" type="application/atom+xml" /><feedburner:emailServiceId>1937748</feedburner:emailServiceId><feedburner:feedburnerHostname>http://www.feedburner.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FJavisTechnicalBlog" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FJavisTechnicalBlog" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FJavisTechnicalBlog" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.rojo.com/add-subscription?resource=http%3A%2F%2Ffeeds.feedburner.com%2FJavisTechnicalBlog" src="http://blog.rojo.com/RojoWideRed.gif">Subscribe with Rojo</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/JavisTechnicalBlog" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FJavisTechnicalBlog" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FJavisTechnicalBlog" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FJavisTechnicalBlog" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:browserFriendly>(Enter a personal message you would like to have appear at the top of your feed.)</feedburner:browserFriendly><entry gd:etag="W/&quot;CUQASH07fSp7ImA9WxRRE0k.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-8080596857609943595</id><published>2008-09-25T12:23:00.005+02:00</published><updated>2008-09-25T13:49:09.305+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-25T13:49:09.305+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Castle" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><title>Singleton WCF Proxy</title><content type="html">In WCF, creating a proxy is a heavy operation, so if you are experiencing performance slowdown you should definitely look at this area. One of the possible solutions to tackle this problem is to reuse your proxies across your application threads, either implementing a singleton or a pool, but in any case bear in mind that proxy reusability is only advisable in some scenarios (see &lt;a href="http://blogs.msdn.com/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx"&gt;this&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx"&gt;this&lt;/a&gt; for the considerations).&lt;br /&gt;Ok, so let's say that we want to go for a singleton proxy and we use Castle as a DI container to handle the proxy instances.&lt;br /&gt;In theory the implementation would be as easy as this&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="TestService"&lt;/span&gt;&lt;br /&gt;                  &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="WCFTest.Contracts.ITestService, WCFTest.Contracts"&lt;/span&gt;&lt;br /&gt;                  &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="WCFTest.Proxies.TestProxy, WCFTest.Proxies"&lt;/span&gt; &lt;br /&gt;                  &lt;span class="attr"&gt;lifestyle&lt;/span&gt;&lt;span class="kwrd"&gt;="singleton"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;       &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Where ITestService is the WCF contract and TestProxy is the proxy for that contract... End of the story? Not quite. The problem here arises when for any reason the channel associated to the proxy gets faulted. You probably already know that &lt;a href="http://jeffbarnes.net/portal/blogs/jeff_barnes/archive/2007/04/24/wcf-your-proxy-can-only-fault-once.aspx"&gt; a faulted proxy can no longer connect to a service&lt;/a&gt; and in order to connect again to it there is no option than throwing away the faulted proxy instance and using a new one.&lt;br /&gt;So it seems that the singleton approach doesn't suit our needs; we need to find a way of recreating proxy instances only when a proxy is in faulted state, something like &lt;a href="http://bloggingabout.net/blogs/erwyn/archive/2006/12/09/WCF-Service-Proxy-Helper.aspx"&gt;this approach&lt;/a&gt; but fit in our DI container. Good news is that Castle gives the possibility to &lt;a href="http://castleproject.org/container/documentation/trunk/usersguide/lifestyles.html"&gt;define custom lifestyle managers for our instances&lt;/a&gt;; we just need to implement the ILifestyleManager interface (or like in the following code snippet, the abstract class AbstractLifestyleManager) and provide the expected behavior.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// Singleton WCF Proxy Lifestyle Manager&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SingletonWCFProxyLifestyleManager : AbstractLifestyleManager&lt;br /&gt;{&lt;br /&gt;    &lt;span class="preproc"&gt;#region&lt;/span&gt; properties&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; instance;&lt;br /&gt;    &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="preproc"&gt;#region&lt;/span&gt; overriden methods&lt;br /&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// Resolves the specified instance from the context.&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name="context"&amp;gt;The context.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;The resolved object&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Resolve(Castle.MicroKernel.CreationContext context)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;lock&lt;/span&gt; (&lt;span class="kwrd"&gt;base&lt;/span&gt;.ComponentActivator)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="rem"&gt;//If the instance does not exists it is resolved&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.instance == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;this&lt;/span&gt;.instance = &lt;span class="kwrd"&gt;base&lt;/span&gt;.Resolve(context);&lt;br /&gt;            }&lt;br /&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                ICommunicationObject communicationObject = &lt;span class="kwrd"&gt;this&lt;/span&gt;.instance &lt;span class="kwrd"&gt;as&lt;/span&gt; ICommunicationObject;&lt;br /&gt;                &lt;span class="rem"&gt;//If the proxy is in faulted state, it's aborted and&lt;/span&gt;&lt;br /&gt;                &lt;span class="rem"&gt;//a new proxy is created&lt;/span&gt;&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (communicationObject != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp;&lt;br /&gt;                    communicationObject.State == CommunicationState.Faulted)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;                    {&lt;br /&gt;                        communicationObject.Abort();&lt;br /&gt;                    }&lt;br /&gt;                    &lt;span class="kwrd"&gt;catch&lt;/span&gt; { }&lt;br /&gt;&lt;br /&gt;                    &lt;span class="kwrd"&gt;this&lt;/span&gt;.instance = &lt;span class="kwrd"&gt;base&lt;/span&gt;.Resolve(context);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.instance;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// Releases unmanaged and - optionally - managed resources&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Dispose()&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.instance != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;base&lt;/span&gt;.Release(&lt;span class="kwrd"&gt;this&lt;/span&gt;.instance);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// Releases the specified instance.&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name="instance"&amp;gt;The instance.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Release(&lt;span class="kwrd"&gt;object&lt;/span&gt; instance)&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Then we need to change the objects configuration file to use our custom implementation.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="TestService"&lt;/span&gt;&lt;br /&gt;                  &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="WCFTest.Contracts.ITestService, WCFTest.Contracts"&lt;/span&gt;&lt;br /&gt;                  &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="WCFTest.Proxies.TestProxy, WCFTest.Proxies"&lt;/span&gt; &lt;br /&gt;                  &lt;span class="attr"&gt;lifestyle&lt;/span&gt;&lt;span class="kwrd"&gt;="custom"&lt;/span&gt;&lt;br /&gt;                  &lt;span class="attr"&gt;customLifestyleType&lt;/span&gt;&lt;span class="kwrd"&gt;="WCFTest.Common.SingletonWCFProxyLifestyleManager, WCFTest.Common"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;       &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Well, I hope that if you are using Castle to manage singleton WCF proxies, this post will be helpful.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f09%2fsingleton-wcf-proxy.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f09%2fsingleton-wcf-proxy.html&amp;bgcolor=476B8E" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/8080596857609943595/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=8080596857609943595" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/8080596857609943595?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/8080596857609943595?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/402722792/singleton-wcf-proxy.html" title="Singleton WCF Proxy" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/09/singleton-wcf-proxy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08BSXo6eip7ImA9WxdUEUU.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-3770613807739657916</id><published>2008-07-23T20:37:00.006+02:00</published><updated>2008-07-27T20:04:18.412+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-27T20:04:18.412+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ADO.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Certifications" /><title>ADO.NET 3.5 certification exam results</title><content type="html">Back in April I blogged about my experience sitting for &lt;a href="http://javicrespotech.blogspot.com/2008/04/adonet-35-certification-exam.html"&gt;the new ADO.NET 3.5 exam beta&lt;/a&gt;. Well, Microsoft published last week the results for this exam and for &lt;a href="http://www.microsoft.com/learning/en/us/exams/70-562.mspx"&gt;ASP.NET 3.5&lt;/a&gt; one too, and I'm glad to say that I passed; here it goes my new logo :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bp3.blogger.com/_rIotvlm4gjQ/SIy1uHYNczI/AAAAAAAAACk/nedU14cDNAA/s1600-h/MCTS(rgb)_1101.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_rIotvlm4gjQ/SIy1uHYNczI/AAAAAAAAACk/nedU14cDNAA/s320/MCTS(rgb)_1101.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5227753071329506098" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;These exams should be live shortly, so if you are interested in taking them, you might want to check out &lt;a href="http://blogs.msdn.com/gerryo/"&gt;Gerry's blog&lt;/a&gt; for the latest news.&lt;br /&gt;Btw, I highly recommend taking &lt;a href="http://vishaljoshi.blogspot.com/2005/11/microsoft-beta-exams.html"&gt;beta exams&lt;/a&gt;: they help to keep up to and discover new technologies and they have the advantage of being free of charge!</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/3770613807739657916/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=3770613807739657916" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/3770613807739657916?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/3770613807739657916?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/347630414/adonet-35-certification-exam-results.html" title="ADO.NET 3.5 certification exam results" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp3.blogger.com/_rIotvlm4gjQ/SIy1uHYNczI/AAAAAAAAACk/nedU14cDNAA/s72-c/MCTS(rgb)_1101.gif" height="72" width="72" /><feedburner:origLink>http://javicrespotech.blogspot.com/2008/07/adonet-35-certification-exam-results.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8CRXg7fip7ImA9WxdWFEg.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-2101747307881781947</id><published>2008-07-07T20:05:00.003+02:00</published><updated>2008-07-07T20:21:04.606+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-07T20:21:04.606+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Team Foundation Server" /><title>TFS wish list</title><content type="html">I've been using TFS 2008 for a while, and despite the new good features (easier installation, offline support, better build management, built-in continuous integration, etc), I'm a little bit disappointed to see that some limitations existent in the previous TFS 2005 haven't been solved yet in this new release.&lt;br /&gt;Don't get me wrong; I think that TFS is a great product but, moving forward, this would be my wish list for the following TFS version, &lt;a href="http://msdn.microsoft.com/en-us/vstudio/bb725993.aspx"&gt;codename Rosario&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Server Side Check-in policies&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/team_foundation/archive/2005/04/15/408700.aspx"&gt;Checkin policies&lt;/a&gt; are a very nice feature in TFS; for example you can enforce that before anyone checks a changeset in, he has to associate it with a Work item, or he's had to build the solution and run FxCop, etc... The concept is good, but I don't like the way that it has been implemented: Checkin policies are enforced at &lt;strong&gt;client side&lt;/strong&gt; rather than at &lt;strong&gt;server side&lt;/strong&gt; and this has some bad implications, for example the inconvenience of deploying custom checkin policies.&lt;br /&gt;TFS explorer comes along with some policies but as you may have expected you can create your own custom policies; actually you might want to check the policies that &lt;a href="http://msdn.microsoft.com/en-us/tfs2008/bb980963.aspx"&gt;TFS 2008 Power tools&lt;/a&gt; provides before creating a new one.&lt;br /&gt;So far so good, the catch is that after getting one way or another your custom policy, in order to enforce it, you have to make sure that everyone in your team deploys it in his workstation or it won't be run when they check in and, on top of that, they will get a nasty policy loading error :( As you can see &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1987073&amp;amp;SiteID=1"&gt;here&lt;/a&gt;, there are people out there that have the same frustration...&lt;br /&gt;I've been focusing in the inconvenience of deployment that this client-side model implies, but what about security? So what if a developer decides to change any of the policies implementation to disable check-in validation?... Well, you might be wondering why somebody would want to do that, but if check-in policies were enforced at server side you wouldn't be wondering.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;TFS application tier running in a 64bit box&lt;/strong&gt;&lt;br /&gt;There is not much to say about this, the header text is self explanatory :)&lt;br /&gt;Even if you go for a non single server deployment where you could use a x64 for the data tier (SQL Server), TFS application tier still needs to be installed in a x32 bit machine...&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Branching: carry source history to the branch&lt;/strong&gt;&lt;br /&gt;As Brendan Lawlor pointed out &lt;a href="http://blog.decaresystems.ie/index.php/2007/04/18/more-limitations-of-tfs-branching/"&gt;here&lt;/a&gt;, when a branch is created in TFS 2005, its history starts from its creation point of time so the branch doesn't "remember" any of the changes that were made on its source.&lt;br /&gt;This means, for example, that comparing a changeset from the branch against a change made back in time on the head becomes a non straightforward task, especially if you happen to be in a situation where nested branches are required. &lt;br /&gt;Unfortunately, after a simple test in TFS 2008, you will notice that this problem hasn't been solved yet.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;TFS event subscription GUI tool&lt;/strong&gt;&lt;br /&gt;It would be great if TFS came along with a proper GUI tool to handle subscriptions for events remotely, something like this &lt;a href="http://www.codeplex.com/tfseventsubscription"&gt;open source tool&lt;/a&gt; provides but not only limited to work item events. &lt;br /&gt;Even for something so simple like sending a notification email when a build fails the TFS Project Alerts screen is useless so you have to end up using the &lt;a href="http://www.codeplex.com/VSTSGuidance/Wiki/View.aspx?title=How%20to%20receive%20notification%20when%20a%20build%20has%20failed&amp;referringTitle=Build%20Practices%20at%20a%20Glance"&gt;bissubscribe command tool&lt;/a&gt;, which by the way can only be run locally on the TFS application server. &lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;That was my list; feel free to post your own thoughts and comments about it.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f07%2ftfs-wish-list.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f07%2ftfs-wish-list.html&amp;bgcolor=476B8E" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/2101747307881781947/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=2101747307881781947" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/2101747307881781947?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/2101747307881781947?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/329095552/tfs-wish-list.html" title="TFS wish list" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/07/tfs-wish-list.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UMQns5fip7ImA9WxdRGUk.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-649751404535355212</id><published>2008-06-08T14:47:00.009+02:00</published><updated>2008-06-08T20:21:23.526+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-08T20:21:23.526+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Castle" /><category scheme="http://www.blogger.com/atom/ns#" term="AOP" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><category scheme="http://www.blogger.com/atom/ns#" term="Enterprise Library" /><title>Dependency Injection in WCF Services Part 4</title><content type="html">In the &lt;a href="http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services_17.html"&gt;last post of these series&lt;/a&gt;, I showed a first approach on how to use Castle Interceptors along with WCF Castle Facility to apply cross-cutting concerns in the Service Layer. The Log sample interceptor that I used for this last post was hopefully enough to get the flavour, but I think that a more compelling sample is needed to demonstrate what these interceptors are really capable of. &lt;br /&gt;I won't leave the Enterprise Library though, but instead of the Logging Application Block I'll use the Validation Application Block for this demo.&lt;br /&gt;&lt;br /&gt;Let's take the sample that I've been using in these series and add a Save function in the Customer Service.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DISample.Service&lt;br /&gt;{&lt;br /&gt;    &lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomerService:ICustomerService&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; properties&lt;br /&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; ICustomerDataAccess customerDataAccess;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ICustomerDataAccess CustomerDataAccess&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; customerDataAccess; }&lt;br /&gt;            set { customerDataAccess = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; ICustomerService Members&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Customer GetCustomer(&lt;span class="kwrd"&gt;long&lt;/span&gt; id)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; CustomerDataAccess.GetCustomer(id);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Customer SaveCustomer(Customer customer)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; customerDataAccess.SaveCustomer(customer);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;And the unrealistically simple Customer class goes as follows&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DISample.Entity&lt;br /&gt;{&lt;br /&gt;    [DataContract]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Customer&lt;br /&gt;    {&lt;br /&gt;        [DataMember]&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; CustomerId { get; set; }&lt;br /&gt;        [DataMember]&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; String Name { get; set; }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Now we need to meet the requirement that for saving a Customer its Name must be at least 5 characters long and it cannot be longer than 35 characters... The Validation Application Block gets into the game!&lt;br /&gt;&lt;br /&gt;The Validation Application Block added value is that it provides a central repository of rules that can be used across the entire application layers so we don't end up coding the same rule in UI, Service, Data Access...&lt;br /&gt;&lt;br /&gt;The rules can be defined either in configuration files or through .NET attributes; for this sample I'll use the latter, particularly, the StringLengthValidator through its attribute.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DISample.Entity&lt;br /&gt;{&lt;br /&gt;    [DataContract]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Customer&lt;br /&gt;    {&lt;br /&gt;        [DataMember]&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; CustomerId { get; set; }&lt;br /&gt;        &lt;br /&gt;        [StringLengthValidator(5, 35)]&lt;br /&gt;        [DataMember]&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; String Name { get; set; }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The validator is already declared, but we still need to kick it off. The Enterprise Library provides some API helper methods to instatiate validators so as to fire them, for now we'll put that code in the Service implementation.&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomerService:ICustomerService&lt;br /&gt;  {&lt;br /&gt;      ....&lt;br /&gt;      &lt;span class="preproc"&gt;#region&lt;/span&gt; ICustomerService Members&lt;br /&gt;      ......&lt;br /&gt;      &lt;span class="kwrd"&gt;public&lt;/span&gt; Customer SaveCustomer(Customer customer)&lt;br /&gt;      {&lt;br /&gt;          ValidationResults validation = Validation.ValidateFromAttributes&amp;lt;Customer&amp;gt;(customer);&lt;br /&gt;          &lt;span class="kwrd"&gt;if&lt;/span&gt; (!validation.IsValid)&lt;br /&gt;              &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException();&lt;br /&gt;&lt;br /&gt;          &lt;span class="kwrd"&gt;return&lt;/span&gt; customerDataAccess.SaveCustomer(customer);&lt;br /&gt;      }&lt;br /&gt;      &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;And the validation requirement is already fulfilled with this code. If we follow this approach though, we would need to produce a similar code snippet for every method in the service and for each parameter that a method receives. In other words, this looks like a situation where an interceptor would be more than welcome :)&lt;br /&gt;&lt;br /&gt;Let's remove the validation code from the Save method and create the ValidationInterceptor class.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DISample.Interceptor&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ValidationInterceptor:IInterceptor&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; IInterceptor Members&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Intercept(IInvocation invocation)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;object&lt;/span&gt; argument &lt;span class="kwrd"&gt;in&lt;/span&gt; invocation.Arguments)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (argument != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;                {&lt;br /&gt;                    Validator validator = ValidationFactory.CreateValidator(argument.GetType());&lt;br /&gt;                    ValidationResults result = validator.Validate(argument);&lt;br /&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!result.IsValid)&lt;br /&gt;                        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException();&lt;br /&gt;                }&lt;br /&gt;                &lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;As easy as it looks; input parameters are available through the Arguments property of the IInvocation interface so we just need to loop through them and use Enterprise Library Helper methods to fire the validators. &lt;br /&gt;&lt;br /&gt;You may have noticed that I haven't been very informational throwing an InvalidOperationException with no message; however it would be pretty straightforward to create a custom Exception that will carry the information that the Enterprise Library ValidationResult class provides.&lt;br /&gt;&lt;br /&gt;We are almost done, the only thing left is to declare the validation interceptor through Castle configuration file&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;="1.0"&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;="utf-8"&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerService"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.ICustomerService, DISample.Service"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.CustomerService, DISample.Service"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;interceptors&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;interceptor&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;${ValidationInterceptor}&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;interceptor&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;interceptors&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="ValidationInterceptor"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Interceptor.ValidationInterceptor, DISample.Interceptor"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerDataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.ICustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.CustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;So before any method of the Customer class gets call, our interceptor will verify the correctness of the input parameters according to the rules defined through the Validation Application Block. No wonder that there is room for many improvements in that code, but the point that I was trying to make is that the task of apply cross cutting concerns gets much simpler using Castle Interceptors and Enterprise Library Application blocks.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f06%2fdependency-injection-in-wcf-services.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f06%2fdependency-injection-in-wcf-services.html&amp;bgcolor=476B8E" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/649751404535355212/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=649751404535355212" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/649751404535355212?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/649751404535355212?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/327405819/dependency-injection-in-wcf-services.html" title="Dependency Injection in WCF Services Part 4" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/06/dependency-injection-in-wcf-services.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MFR3w4eCp7ImA9WxdSFk8.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-8073004784918248640</id><published>2008-05-22T22:00:00.008+02:00</published><updated>2008-05-24T12:36:56.230+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-24T12:36:56.230+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SQL Server" /><category scheme="http://www.blogger.com/atom/ns#" term="Code generation" /><title>Unique Index Schema Information in SQL Server</title><content type="html">Unique indexes along foreign key constraints are used to model One-To-One relationships in Database model design. In fact, when it comes to the DB design, the only difference between a One-To-One relationship and a One-To-Many relationship is that Unique index. For Data Access code generation purposes the existence of the unique index will effectively tell you, for example if you are generating navigation properties, whether to create a simple entity type navigation (One-To-One) or an entity array type navigation (One-To-Many) between the two entities that take part in the data base relationship.&lt;br /&gt;&lt;br /&gt;In ADO.NET the &lt;a href="http://msdn.microsoft.com/en-us/library/ms254969.aspx"&gt;GetSchema methods&lt;/a&gt; can be used to get Schema information from different Data base provider types; unfortunately for SQL Server Databases unique index information is not provided with that API. Don't panic though, one way or another SQL Server hast to store the unique index information in its catalog tables so after digging into the master database views list for a while, we bump into the table sys_indexes and its is_unique column. An index can be applied upon many columns therefore we'll need to join with sys.index_columns and sys.columns in order to get the column name as well.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; c.[name] &lt;span class="kwrd"&gt;as&lt;/span&gt; column_name, a.[name] &lt;span class="kwrd"&gt;as&lt;/span&gt; index_name, is_unique &lt;br /&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt; sys.indexes a &lt;span class="kwrd"&gt;INNER&lt;/span&gt; &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; sys.index_columns b &lt;br /&gt;&lt;span class="kwrd"&gt;ON&lt;/span&gt; a.object_id = b.object_id &lt;span class="kwrd"&gt;AND&lt;/span&gt; a.index_id = b.index_id &lt;br /&gt;&lt;span class="kwrd"&gt;INNER&lt;/span&gt; &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; sys.columns c &lt;br /&gt;&lt;span class="kwrd"&gt;ON&lt;/span&gt; b.object_id = c.object_id &lt;span class="kwrd"&gt;and&lt;/span&gt; b.column_id = c.column_id &lt;br /&gt;&lt;span class="kwrd"&gt;WHERE&lt;/span&gt; a.object_id = OBJECT_ID(N&lt;span class="str"&gt;'dbo.yourTable'&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2funique-index-schema-information-in-sql.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2funique-index-schema-information-in-sql.html&amp;bgcolor=476B8E" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/8073004784918248640/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=8073004784918248640" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/8073004784918248640?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/8073004784918248640?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/327405820/unique-index-schema-information-in-sql.html" title="Unique Index Schema Information in SQL Server" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/05/unique-index-schema-information-in-sql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUCQHk6eip7ImA9WxdRGUk.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-5588110575247026541</id><published>2008-05-17T13:15:00.003+02:00</published><updated>2008-06-08T20:04:21.712+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-08T20:04:21.712+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Dependency Injection" /><category scheme="http://www.blogger.com/atom/ns#" term="Castle" /><category scheme="http://www.blogger.com/atom/ns#" term="AOP" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><category scheme="http://www.blogger.com/atom/ns#" term="Enterprise Library" /><title>Dependency Injection in WCF Services Part 3</title><content type="html">In the &lt;a href="http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services.html"&gt;first post of these series&lt;/a&gt;, I explained the problems you may run into when applying Dependency Injection in your distributed service layer, and in the &lt;a href="http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services_03.html"&gt;second one&lt;/a&gt; I put the theory in practice using &lt;a href="http://www.castleproject.org/container/facilities/trunk/wcf/index.html"&gt;Castle Windsor WCF Facility&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now that our DI container instantiates our services, we can take advantage of other features not necessarily related to Dependency Injection available in the container. Particularly in this post I'll drift away a bit from dependency injection and I'll focus on the interception capabilities that Castle Windsor framework offers.&lt;br /&gt;&lt;br /&gt;Let's take the sample that I've been using for these series and say for example that we want to use Enterprise Library Application Loggin Block so as to log every method execution in our service object.&lt;br /&gt;A simple implementation would be to include the logging call in the service implementation.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DISample.Service&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomerService:ICustomerService&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; properties&lt;br /&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; ICustomerDataAccess customerDataAccess;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ICustomerDataAccess CustomerDataAccess&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; customerDataAccess; }&lt;br /&gt;            set { customerDataAccess = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; ICustomerService Members&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Customer GetCustomer(&lt;span class="kwrd"&gt;long&lt;/span&gt; id)&lt;br /&gt;        {&lt;br /&gt;            Logger.Write(&lt;span class="str"&gt;"GetCustomer Start"&lt;/span&gt;);&lt;br /&gt;            Customer customer = CustomerDataAccess.GetCustomer(id);&lt;br /&gt;            Logger.Write(&lt;span class="str"&gt;"GetCustomer End"&lt;/span&gt;);&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; customer;&lt;br /&gt;        }&lt;br /&gt;   &lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;So we are leaving the logging responsability to the service class itself... That doesn't sound quite right, does it? The service responsability is to interact with the Data Access layer and/or carry out business process but logging is a cross cutting concern that has nothing to do with the actual service implemenation. Besides, for the sake of code cleanignless and reusability, in my Service code I don't want stuff that is not related to the Service main purpose.&lt;br /&gt;&lt;br /&gt;Then, how we can possibly achieve logging in our service object leaving the logging calls out of our service implementation? Well, we might use &lt;a href="http://en.wikipedia.org/wiki/Decorator_pattern"&gt;the Decorator pattern&lt;/a&gt; for that. This pattern gives the ability to extend the functionality of a class without changing its orginal implementation.&lt;br /&gt;Let's create the CustomerServiceLogginDecorator logging decorator in order to include logging capabilities to our service.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DISample.Service&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomerServiceLoggingDecorator:ICustomerService&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; properties&lt;br /&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; ICustomerService customerService;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ICustomerService CustomerService&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; customerService; }&lt;br /&gt;            set { customerService = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; ICustomerService Members&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Customer GetCustomer(&lt;span class="kwrd"&gt;long&lt;/span&gt; customerId)&lt;br /&gt;        {&lt;br /&gt;            Logger.Write(&lt;span class="str"&gt;"GetCustomer Start"&lt;/span&gt;);&lt;br /&gt;            Customer customer = CustomerService.GetCustomer(customerId);&lt;br /&gt;            Logger.Write(&lt;span class="str"&gt;"GetCustomer End"&lt;/span&gt;);&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; customer;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Notice that the decorator implements the same interface that our service implementation; that's the whole point of the Decorator pattern. The service consumers use the service through its interface (ICustomerService) and it's through the DI container that we specify a particular service implementation for that interface. Therefore, we can create our decorator as a service frontend and inject the actual service implementation into the decorator.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerService"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.ICustomerService, DISample.Service"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.&lt;span style="color:#ff0000;"&gt;CustomerServiceLoggingDecorator&lt;/span&gt;, DISample.Service"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerServiceImpl"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.ICustomerService, DISample.Service"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.CustomerService, DISample.Service"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerDataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.ICustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.CustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Notice as well that, since the decorator uses ICustomerService interface as dependency, the underlying implementation of the service remains hidden and therefore we can use the DI container to inject as many ICustomerService decorators as we wish upon the real service implementation. Let's imagine that we want to add an exception decorator...&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerService"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.ICustomerService, DISample.Service"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.&lt;span style="color:#ff0000;"&gt;CustomerServiceExceptionDecorator&lt;/span&gt;, DISample.Service"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerServiceLogging"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.ICustomerService, DISample.Service"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.&lt;span style="color:#ff0000;"&gt;CustomerServiceLoggingDecorator&lt;/span&gt;, DISample.Service"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerServiceImpl"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.ICustomerService, DISample.Service"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.CustomerService, DISample.Service"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerDataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.ICustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.CustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ok, so we got it, there are no longer cross cutting concerns in my service implementation but probably you´ll have already realized that this solution is not the best either. If we carried on with this approach we'd need to create a decorator for each cross cutting concern in each service, it means that we could end up with a number of decorator classes up to (number of Services)*(number of cross cutting concerns) = let´s call this idea off now!&lt;br /&gt;&lt;br /&gt;Well, it looks like the Decorator Pattern can be the way but we need something to remove from us the burden of creating for a single aspect a bunch of service specific decorators. Fortunately, castle framework comes to our rescue and offers us &lt;a href="http://www.castleproject.org/container/documentation/trunk/usersguide/interceptors.html"&gt;the Interceptor functionality&lt;/a&gt; which allows to create independent and reusable cross cutting concern implementations.&lt;br /&gt;Let´s create our reusable logging interceptor.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Castle.Core.Interceptor;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Practices.EnterpriseLibrary.Logging;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DISample.Interceptor&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; LogginInterceptor:IInterceptor&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; IInterceptor Members&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Intercept(IInvocation invocation)&lt;br /&gt;        {&lt;br /&gt;            Logger.Write(invocation.Method.Name + &lt;span class="str"&gt;" Start"&lt;/span&gt;);&lt;br /&gt;            invocation.Proceed();&lt;br /&gt;            Logger.Write(invocation.Method.Name + &lt;span class="str"&gt;" End"&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;And to start using it, we just have to define it in the castle configuration file.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerService"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.ICustomerService, DISample.Service"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.CustomerService, DISample.Service"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;interceptors&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;interceptor&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;${LoginInterceptor}&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;interceptor&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;interceptors&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="LoginInterceptor"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Interceptor.LoginInterceptor, DISample.Interceptor"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerDataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.ICustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.CustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;That's great, isn't it? We define independent interceptors that can be applied upon any class regardless of its type; Castle will take care of the call flow an interception for us.&lt;br /&gt;&lt;br /&gt;To that's it, we have used Castle framework to apply cross cutting concerns in our WCF Service... But that's not what WCF Custom Behaviours are for? Yes, Custom Behaviours get injected in the WCF call stack and in there you can implement some aspects not related to your service implementation like logging, catching, transaction handling, etc. Besides the &lt;a href="http://msdn.microsoft.com/en-us/library/aa480453.aspx"&gt;Enterprise Library 3.1&lt;/a&gt; comes along with a set of Custom Behaviors for WCF that are nothing more that thin wrappers upon the Application Blocks like the &lt;a href="http://msdn.microsoft.com/en-us/library/cc309334.aspx"&gt;Validation Block Custom Behavior&lt;/a&gt;. Then, why would we want to build Castle Interceptors if we can use the Enterprise Library WCF custom Behaviors?.&lt;br /&gt;&lt;br /&gt;Thinking in terms of the overall application and not only about the service layer, you might decide to apply cross cutting concerns to your web layer, your controller layer, your data access layer, etc. and for that WCF Custom Behaviours have no use. The bottom line is that if you want to use a unique homogeneous mechanish to handle cross cutting concers across all your application layers, WCF Custom Behaviours are not the solution!&lt;br /&gt;&lt;br /&gt;Having said that, in the next post of these series I'll show how to implement a more sophisticated Interceptor than the Logging one I explained in this post; Particularly I'll show what it takes to implement an equivalent of the Enterprise Library WCF Validation Custom Behaviour in a Castle Interceptor.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2fdependency-injection-in-wcf-services_17.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2fdependency-injection-in-wcf-services_17.html&amp;bgcolor=476B8E" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/5588110575247026541/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=5588110575247026541" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/5588110575247026541?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/5588110575247026541?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/327405821/dependency-injection-in-wcf-services_17.html" title="Dependency Injection in WCF Services Part 3" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services_17.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8NQng9cCp7ImA9WxdTFEw.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-1800364193211564221</id><published>2008-05-10T12:20:00.005+02:00</published><updated>2008-05-10T13:28:13.668+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-10T13:28:13.668+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JSON" /><category scheme="http://www.blogger.com/atom/ns#" term="WebServices" /><category scheme="http://www.blogger.com/atom/ns#" term="Ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><title>JSON services in ASP.NET Ajax</title><content type="html">Lately the use of client centric development model in .NET is getting increasingly popular. In contrast to the traditional server model where html tags are rendered in server side and then sent to the browser, the client centric approach consist of the use of asynchronous HTTP requests to retrieve data from server side and then do the html rendering in client side code.&lt;br /&gt;&lt;br /&gt;The main advantage of this client centric approach is that the communication between the browser and the server gets much lighter; the browser doesn't need to post the page to get information from the server, it rather issues asynchronous calls to Web Services, which implement the JSON protocol, for retrieving the data. You might be wondering why XML-SOAP or other XML based RPC protocols are not used instead of that JSON...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt; is a non-markup based language which has some limitations comparing to XML languages (i.e: lack of namespaces) but that simplicity makes it lighter, easier to handle by browsers, and overall more performant and more suitable for this web client scenario.&lt;br /&gt;&lt;br /&gt;Unfortunately there is a catch :( ; since the rendering is done in client side, you'd better forget about using your automatically rendered ASP.NET controls and be prepared to start messing around extensively with javascript code for the rendering... No need to go through that pain though, there are some third party client based controls that implement rendering through javascript libraries, particularly you might want to check what &lt;a href="http://www.codeplex.com/AjaxDataControls"&gt;this open source control library&lt;/a&gt; can offer you.&lt;br /&gt;&lt;br /&gt;Well, now that we have gone through the theory, how can we put that in practice in ASP.NET? How can we implement and consume a JSON service?&lt;br /&gt;ASP.NET Ajax framework provides some built-in mechanisms to handle JSON communication and serialization automatically.&lt;br /&gt;These mechanisms are &lt;strong&gt;Page Methods&lt;/strong&gt;, &lt;strong&gt;Ajax Web Services&lt;/strong&gt; and &lt;strong&gt;Ajax WCF Services&lt;/strong&gt; and I'm going to spend the rest of this post to do a brief walkthrough on them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Page methods&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;A page method is a static function marked as a web method and declared within the page code behind. This function can be called from javascript code through a predefined class/keyword called &lt;strong&gt;PageMethods&lt;/strong&gt;. Let's take a look in a sample step by step.&lt;br /&gt;&lt;br /&gt;First the Page method execution has to be enabled in the asp.net ScriptManager.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;="scriptManager"&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;="server"&lt;/span&gt; &lt;span class="attr"&gt;EnablePageMethods&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Now it's time to implement the static web method in the page's code behind.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; _Default : System.Web.UI.Page&lt;br /&gt;{&lt;br /&gt;    [WebMethod]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; String ToUpper(&lt;span class="kwrd"&gt;string&lt;/span&gt; name)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; name.ToUpper();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Finally, the method is consumed from a script included in the page. As I said before the call execution follows an asynchronous pattern, therefore in the sample below if the operation succeds the resulting string in upper case is passed to the OnSucceded method, otherwise the OnFailed method receives the .NET exception.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; ToUpper(name)&lt;br /&gt;{&lt;br /&gt;    PageMethods.StringHandler&lt;br /&gt;    .ToUpper(name, OnSuccedeed, OnFailed);&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; OnSuccedeed(res)&lt;br /&gt;{&lt;br /&gt;    alert(res);&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; OnFailed(error)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="rem"&gt;// Alert user to the error.&lt;/span&gt;&lt;br /&gt;    alert(error.get_message());&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Web Services&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;One of the main differences between Page Methods and Ajax Web Services is that Page Methods can only be used by a single Page and Web Services can be used from as many pages as it’s needed. Needlees to say, both Ajax Web Services and Page Methods use JSON as communication protocol. Let's rework the previous example to use Web Services.&lt;br /&gt;&lt;br /&gt;First the HTTP Handler that will serve AJAX Web services requests and responses needs to be included in the web.config file.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;httpHandlers&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;remove&lt;/span&gt; &lt;span class="attr"&gt;verb&lt;/span&gt;&lt;span class="kwrd"&gt;="*"&lt;/span&gt; &lt;span class="attr"&gt;path&lt;/span&gt;&lt;span class="kwrd"&gt;="*.asmx"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;verb&lt;/span&gt;&lt;span class="kwrd"&gt;="*"&lt;/span&gt; &lt;span class="attr"&gt;path&lt;/span&gt;&lt;span class="kwrd"&gt;="*.asmx"&lt;/span&gt; &lt;span class="attr"&gt;validate&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Next step is to create a web service, which I'll call StringHandler.asmx. The Web Service's class needs to be marked with the ScriptService attribute and ToUpper web method to be implemented.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; JsonServicesSample&lt;br /&gt;{&lt;br /&gt;    [ScriptService]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; StringHandler : System.Web.Services.WebService&lt;br /&gt;    {&lt;br /&gt;        [WebMethod]&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToUpper(String input)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; input.ToUpper();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;We are getting there, now it's just to include the server through the ScriptManager...&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;="ScriptManager1"&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;="server"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Services&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:ServiceReference&lt;/span&gt;&lt;br /&gt;          &lt;span class="attr"&gt;Path&lt;/span&gt;&lt;span class="kwrd"&gt;="~/StringHandler.asmx"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Services&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;and everything is ready to retrieve data from the client script.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; ToUpper(name)&lt;br /&gt;{&lt;br /&gt;    JsonServicesSample.StringHandler&lt;br /&gt;    .ToUpper(name, OnSuccedeed, OnFailed);&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; OnSuccedeed(res)&lt;br /&gt;{&lt;br /&gt;    alert(res);&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; OnFailed(error)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="rem"&gt;// Alert user to the error.&lt;/span&gt;&lt;br /&gt;    alert(error.get_message());&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;WCF Services&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The .NET 3.5 framework release came along with some fixes and extensions upon the early WCF .NET 3.0 version; one of those extensions is the webHttpBinding binding which implements JSON serialization and communication protocol.&lt;br /&gt;So for those who use VS2008 and .NET 3.5 let's rework the sample for the last time.&lt;br /&gt;&lt;br /&gt;First of all the service implementation has to be changed to include the WCF contract attributes; for the sake of simplicity I won't create a separate interface for the contract, I'd rather apply the contract attributes in the implementation itself.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; JsonServicesSample&lt;br /&gt;{&lt;br /&gt;    [ServiceContract&lt;br /&gt;        (Namespace=&lt;span class="str"&gt;"JsonServices.Contract.Sample"&lt;/span&gt;)]&lt;br /&gt;    [AspNetCompatibilityRequirements(&lt;br /&gt;            RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; StringHandler : System.Web.Services.WebService&lt;br /&gt;    {&lt;br /&gt;        [OperationContract]&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToUpper(String input)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; input.ToUpper();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;On top of the WCF contract attributes, the &lt;strong&gt;AspNetCommpatibilityRequirements&lt;/strong&gt; attribute is provided. That attribute will allow the WCF service to have access to the HTTP context (i.e.: ASP.NET Session variable) and besides, it will tell the runtime to ensure at Service Host creation time that all the enpoints defined for the JSON contract use the Web http binding.&lt;br /&gt;Now it's time to define the service and its endpoint in Web.config file, notice that the AspNetCompatibilityRequirements attribute needs to be defined at the ServiceHost level as well.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.serviceModel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;behaviors&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;endpointBehaviors&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;behavior&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="StringHandlerBehavior"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;enableWebScript&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;behavior&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;endpointBehaviors&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;behaviors&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;serviceHostingEnvironment&lt;/span&gt; &lt;span class="attr"&gt;aspNetCompatibilityEnabled&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;services&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;service&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="JsonServicesSample.StringHandler"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;endpoint&lt;/span&gt; &lt;span class="attr"&gt;address&lt;/span&gt;&lt;span class="kwrd"&gt;=""&lt;/span&gt;&lt;br /&gt;                  &lt;span class="attr"&gt;behaviorConfiguration&lt;/span&gt;&lt;span class="kwrd"&gt;="StringHandlerBehavior"&lt;/span&gt;&lt;br /&gt;                  &lt;span class="attr"&gt;binding&lt;/span&gt;&lt;span class="kwrd"&gt;="webHttpBinding"&lt;/span&gt;&lt;br /&gt;                  &lt;span class="attr"&gt;contract&lt;/span&gt;&lt;span class="kwrd"&gt;="JsonServicesSample.StringHandler"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;services&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;system.serviceModel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Since the service will be deployed in a IIS environment, the StringHandler.svc is created.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;%@ServiceHost&lt;br /&gt;   Service="JsonServicesSample.StringHandler" %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;The server configuration tasks are done, now the service reference needs to be included in the page's Script Manager&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;="ScriptManager1"&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;="server"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Services&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:ServiceReference&lt;/span&gt;&lt;br /&gt;          &lt;span class="attr"&gt;Path&lt;/span&gt;&lt;span class="kwrd"&gt;="~/StringHandler.svc"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Services&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;And everything is ready to start using the service from client side script code.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; ToUpper(name)&lt;br /&gt;{&lt;br /&gt;    JsonServices.Contract.Sample.StringHandler&lt;br /&gt;    .ToUpper(name, OnSuccedeed, OnFailed);&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; OnSuccedeed(res)&lt;br /&gt;{&lt;br /&gt;    alert(res);&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; OnFailed(error)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="rem"&gt;// Alert user to the error.&lt;/span&gt;&lt;br /&gt;    alert(error.get_message());&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;You may have already noticed that instead of using the service .NET class namespace (JsonServicesSample) as we did in the Web Services sample, this proxy uses JsonService.Contract.Sample, but what the ** is that? Well if you go back to the StringHandler implementation you'll notice that the ServiceContract defines a namespace...&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;[ServiceContract&lt;br /&gt;(Namespace=&lt;span class="str"&gt;"JsonServices.Contract.Sample"&lt;/span&gt;)]&lt;/pre&gt;&lt;br /&gt;So the bottom line is that &lt;strong&gt;WCF client-side proxys use the contract namespace in contrast with Ajax Web services which use the .NET class namespace instead.&lt;/strong&gt;.&lt;br /&gt;And that's it, our WCF service and client are ready. Before finishing though, it's worth mentioning the &lt;strong&gt;WebScriptServiceHostFactory&lt;/strong&gt; Service Host Factory and how it can help us to remove configuration from Json WCF services.&lt;br /&gt;Comparing to the Web service solution, in WCF sample an additional step was taken in order to define the service and endpoint configuration. If you want to keep it simple and skip that step you can do it using the WebScriptServiceHostFactory Service Host factory. This factory creates ServiceHosts with the default services, endpoints and behaviours suitable for this Json web environment so explicit configuration is no longer needeed&lt;br /&gt;In order to achieve it, if we look at the sample then, the service factory is declared in the .svc file...&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;%@ServiceHost&lt;br /&gt;   Service="JsonServicesSample.StringHandler"&lt;br /&gt;   Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;...so the WCF configuration can be now wiped out from the web.config file.&lt;br /&gt;&lt;br /&gt;That's all folks! I hope that if you weren't familiar with this subject this rather long post has given you an idea of what it takes to implement basic Json services in ASP.NET.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2fjson-services-in-aspnet-ajax.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2fjson-services-in-aspnet-ajax.html&amp;bgcolor=476B8E" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/1800364193211564221/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=1800364193211564221" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/1800364193211564221?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/1800364193211564221?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/327405822/json-services-in-aspnet-ajax.html" title="JSON services in ASP.NET Ajax" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/05/json-services-in-aspnet-ajax.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUMQX4-fip7ImA9WxdSEE8.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-6339035034018055280</id><published>2008-05-03T15:49:00.011+02:00</published><updated>2008-05-17T14:11:20.056+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-17T14:11:20.056+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Dependency Injection" /><category scheme="http://www.blogger.com/atom/ns#" term="Castle" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><title>Dependency Injection in WCF Services Part 2</title><content type="html">In the &lt;a href="http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services.html"&gt;first post of these series&lt;/a&gt;, I explained the problems you may run into when applying Dependency Injection in your distributed service layer and some of the available solutions to get them around, mainly focusing WCF services. Let's finish off with the theory and put one of those solutions in practice, shall we? In this post I'll rework the sample that I used in my previous post to show the Service Locator pattern in order to use Dependency Injection instead. As in the project that I'm currently working on we are using Castle, I'll use WCF Castle facility to do the service injection.&lt;br /&gt;&lt;br /&gt;Let's take then my Service Locator sample&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomerService:ICustomerService&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; ICustomerService Members&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Customer GetCustomer(&lt;span class="kwrd"&gt;long&lt;/span&gt; id)&lt;br /&gt;        {&lt;br /&gt;            ICustomerDataAccess da;&lt;br /&gt;            da = Global.Container.Resolve&amp;lt;ICustomerDataAccess&amp;gt;();&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; da.GetCustomer(id);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;and rework it to use Dependency Injection&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomerService:ICustomerService&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; properties&lt;br /&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; ICustomerDataAccess customerDataAccess;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ICustomerDataAccess CustomerDataAccess&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; customerDataAccess; }&lt;br /&gt;            set { customerDataAccess = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; ICustomerService Members&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Customer GetCustomer(&lt;span class="kwrd"&gt;long&lt;/span&gt; id)&lt;br /&gt;        {&lt;br /&gt;        &lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; CustomerDataAccess.GetCustomer(id);&lt;br /&gt;        }&lt;br /&gt;    &lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;You can notice that with those changes our service class is no longer dependant on the DI container for resolving the CustomerDataAccess implementation like it is in the Service Locator example. Instead, the Data access dependency is a property that can be injected by an external agent, which can be whatever DI container we want to use or even a simple factory... Let's focus on this sample though!&lt;br /&gt;&lt;br /&gt;The next step is to create a Castle configuration file called "Objects.xml" where both service and data access objects are defined.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;="1.0"&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;="utf-8"&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerService"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.ICustomerService, DISample.Service"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.Service.CustomerService, DISample.Service"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomerDataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;service&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.ICustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;br /&gt;               &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="DISample.DataAccess.CustomerDataAccess, DISample.DataAccess"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;component&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;components&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;As you can see there is no need to connect the DataAccess dependency to the Service object in the configuration file; Castle automatically wires it up.&lt;br /&gt;&lt;br /&gt;Now that the Service code is ready for injection and the objects are defined in a configuration file, it's time to use the WCF facility to do the actual service injection.&lt;br /&gt;In order to install the dependency injection behavior, Castle facility uses a a custom WCF ServiceHost. Then, for a non-IIS 6.0 environment and asuming that the service and the endpoint configuration are located in an external configuration file, our WCF host creation would look something like this.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;WindsorContainer container = &lt;span class="kwrd"&gt;new&lt;/span&gt; WindsorContainer(&lt;span class="str"&gt;"Objects.xml"&lt;/span&gt;);&lt;br /&gt;Uri uri = &lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(&lt;span class="str"&gt;"net.tcp://localhost/DISample"&lt;/span&gt;);&lt;br /&gt;WindsorServiceHost host = &lt;span class="kwrd"&gt;new&lt;/span&gt; WindsorServiceHost(container.Kernel, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(CustomerService), uri);&lt;br /&gt;host.Open();&lt;/pre&gt;&lt;br /&gt;We instantiate the Windsor container with our object configuration file so as to be used by the custom service host... and that's all for non-IIS6.0 hosts!&lt;br /&gt;&lt;br /&gt;As you may already know, ServiceHost instatiatation model for WCF services host under II6.0 is different: We don't explictly create the ServiceHost; instead ServiceHosts are created by a ServiceHostFactory on each HTTP request.&lt;br /&gt;WCF castle facility provides a custom ServiceHostFactory that can be specified for its use in IIS6 .svc service files. Let's change the default CustomerService.svc accordingly.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;%@ ServiceHost Service="CustomerService"&lt;br /&gt;Factory="Castle.Facilities.WcfIntegration.WindsorServiceHostFactory, Castle.Facilities.WcfIntegration" %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Where the value of attribute Service must match either the id of our service in Castle configuration file or the service type itself.&lt;br /&gt;Are we missing anything? We haven't created the Windsor Container yet, have we?. Like I said before in II6.0 environments ServiceHosts are created by http request, but would it be wise to apply the same approach for creating the WindsorContainer? I don't think so! Don't panic though, WCF facility has already covered that. Since we are in a web environment, we can use the Global.asax Application_Start event to create our Windsor Container and then register it through an available method in the custom ServiceHostFactory.&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Global : System.Web.HttpApplication&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Application_Start(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            WindsorContainer container = &lt;span class="kwrd"&gt;new&lt;/span&gt; WindsorContainer(&lt;span class="str"&gt;"Objects.xml"&lt;/span&gt;);&lt;br /&gt;            WindsorServiceHostFactory.RegisterContainer(container.Kernel);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We are done! What's next then? One of the things that I pointed out &lt;a href="http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services.html"&gt;in the first post of this series&lt;/a&gt; is that no AOP features can be applied upon objects that are not handled by the DI container... That's no longer a problem for us!&lt;br /&gt;In the &lt;a href="http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services_17.html"&gt;next post of these series&lt;/a&gt; I'll show how we can use castle interceptors to apply cross cutting concerns upon service objects.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2fdependency-injection-in-wcf-services_03.html"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2fdependency-injection-in-wcf-services_03.html&amp;amp;bgcolor=476B8E" border="0" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/6339035034018055280/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=6339035034018055280" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/6339035034018055280?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/6339035034018055280?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/327405823/dependency-injection-in-wcf-services_03.html" title="Dependency Injection in WCF Services Part 2" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services_03.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUGQH4_cSp7ImA9WxdTF0o.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-5114530709625080319</id><published>2008-05-01T18:50:00.034+02:00</published><updated>2008-05-14T17:00:21.049+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-14T17:00:21.049+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Dependency Injection" /><category scheme="http://www.blogger.com/atom/ns#" term="WebServices" /><category scheme="http://www.blogger.com/atom/ns#" term="Castle" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><title>Dependency Injection in WCF Services</title><content type="html">To use &lt;a href="http://www.martinfowler.com/articles/injection.html#FormsOfDependencyInjection"&gt;Dependency Injection&lt;/a&gt; in a distributed service layer is not a trivial task. Either if you use Web Services or WCF, your services are created by the .NET engine, so somehow you need to find a way to inject your Dependency Injection Container in there.&lt;br /&gt;&lt;br /&gt;You might as well let the engine create your service and then use the &lt;a href="http://www.martinfowler.com/articles/injection.html#UsingAServiceLocator"&gt;Service Locator pattern&lt;/a&gt; to hook up the underlying layer.&lt;br /&gt;In the following code snippet we use &lt;a href="http://www.castleproject.org/"&gt;Castle container&lt;/a&gt; as a Service Locator to retrieve the Data Access Layer instance that is used from our WCF service.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomerService:ICustomerService&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; ICustomerService Members&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Customer GetCustomer(&lt;span class="kwrd"&gt;long&lt;/span&gt; id)&lt;br /&gt;        {&lt;br /&gt;            ICustomerDataAccess da;&lt;br /&gt;            da = Global.Container.Resolve&amp;lt;ICustomerDataAccess&amp;gt;();&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; da.GetCustomer(id);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;In the above example, you'll notice that apart from using &lt;a href="http://www.martinfowler.com/articles/injection.html#ServiceLocatorVsDependencyInjection"&gt;a slightly different pattern&lt;/a&gt; for creating the Data Access object, the service instantiation is not handled by our DI container and this has some bad implications. Some DI containers, such as Castle or Spring.NET, offer &lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming"&gt;AOP&lt;/a&gt; features but those features can only be applied upon objects instantiated by the container. So the bottom line is that in this scenario we can't use those AOP frameworks upon our service objects.&lt;br /&gt;&lt;br /&gt;So for some scenarios Service Locator pattern could be just alright, but what if we still want to go for a pure Dependency Injection pattern in our service layer? How can we get around the service creation problem?&lt;br /&gt;&lt;br /&gt;If you are using Web Services I'm afraid you don't have many options. Comparing to WCF, Web services is not a very configurable technology and the only way to intercept requests is to replace the ASP.NET default HttpHandler with a custom one, which handles the requests/responses and the service object creation. Good news are that if you are using &lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt;, you don't need to create the handler yourself; there is a &lt;a href="http://www.springframework.net/doc-latest/reference/html/webservices.html"&gt;custom HttpHandler implementation&lt;/a&gt; in the framework that you can use for that purpose.&lt;br /&gt;&lt;br /&gt;If you are using WCF in your service layer, congratulations :) WCF is a highly configurable technology and in fact it provides AOP features through the injection of &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163302.aspx"&gt;custom behaviors&lt;/a&gt;. Using this extensibility &lt;a href="http://orand.blogspot.com/"&gt;Oran&lt;/a&gt; gives us the solution to our problem &lt;a href="http://orand.blogspot.com/2006/10/wcf-service-dependency-injection.html"&gt;here&lt;/a&gt;. As you can read in that post, for creating new service instances WCF uses a factory, which implements IInstanceProvider ... Great news are that we can create a custom behavior that replaces the default IInstanceProvider factory implementation with our own implementation, and in there we can hook up our DI Container.&lt;br /&gt;To cut a long story short, Oran creates an IInstanceProvider implementation that uses Spring.NET container for service objects creation.&lt;br /&gt;&lt;br /&gt;If you are not using Spring.NET, don't panic :) there are also implementations available &lt;a href="http://www.ayende.com/Blog/archive/2007/06/12/WCF-Windsor-Integration.aspx"&gt;for Castle&lt;/a&gt; (created by &lt;a href="http://www.ayende.com/"&gt;Ayende&lt;/a&gt;) and &lt;a href="http://weblogs.asp.net/cibrax/archive/2007/12/13/wcf-dependency-injection-behavior.aspx"&gt;for ObjectBuilder&lt;/a&gt; (created by &lt;a href="http://weblogs.asp.net/cibrax/default.aspx"&gt;Pablo M. Cibraro&lt;/a&gt;) that follow similar approaches than Oran's. Even if you are using Spring.NET, you might as well use &lt;a href="http://plainoldstan.blogspot.com/2008/03/source-code-for-amendments-to-oran.html"&gt;Stan's ammendments&lt;/a&gt; to Oran's solution.&lt;br /&gt;&lt;br /&gt;To sum up, in this post we have explored some different options to implement Dependency Injection in our Service Layer depending on the distributed technology (WebServices and WCF) and on the DI container (Spring.NET, Castle..) used.&lt;br /&gt;&lt;br /&gt;In the &lt;a href="http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services_03.html"&gt;next post of these series&lt;/a&gt;, I'll put these concepts in practice using the WCF Dependency Injection Castle facility.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2fdependency-injection-in-wcf-services.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fjavicrespotech.blogspot.com%2f2008%2f05%2fdependency-injection-in-wcf-services.html&amp;bgcolor=476B8E" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/5114530709625080319/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=5114530709625080319" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/5114530709625080319?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/5114530709625080319?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/327405824/dependency-injection-in-wcf-services.html" title="Dependency Injection in WCF Services" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/05/dependency-injection-in-wcf-services.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEACSH04eyp7ImA9WxdTFEw.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-9177220554612219265</id><published>2008-04-29T19:56:00.001+02:00</published><updated>2008-05-10T12:52:49.333+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-10T12:52:49.333+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ADO.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Certifications" /><category scheme="http://www.blogger.com/atom/ns#" term="LINQ" /><title>ADO.NET 3.5 Certification exam</title><content type="html">A few days ago I sat for the beta exam &lt;a href="http://www.microsoft.com/learning/exams/70-561.mspx"&gt;70-561 .NET Framework 3.5 ADO.NET&lt;/a&gt;. This is the second exam that I've taken for the new .NET 3.5 certifications generation; at the end of last year I took &lt;a href="http://www.microsoft.com/learning/exams/70-503.mspx"&gt;70-503 WCF's exam&lt;/a&gt; and I recently got the &lt;a href="http://blogs.msdn.com/gerryo/archive/2008/04/14/exams-live-today.aspx"&gt;results&lt;/a&gt; with a happy end for me :)&lt;br /&gt;&lt;br /&gt;In 70-561 exam besides traditional topics such as ADO.NET connected data(Commands, DataReaders, etc) and ADO.NET disconnected data (DataSets, DataTables, etc), there is plenty of new stuff that you'd better be familiar with if you want to pass! One of those things is LINQ and LINQ to SQL, which I didn't find particularly difficult maybe cause I've had the chance to work with it.&lt;br /&gt;&lt;br /&gt;If you are not familiar with LINQ to SQL, my buddy &lt;a href="http://www.sidarok.com/web/blog/index.php"&gt;Sidar&lt;/a&gt; came up with a great &lt;a href="http://www.sidarok.com/web/blog/content/2008/04/21/a-brief-introduction-to-linq-to-sql.html"&gt;introduction post&lt;/a&gt; and Scott Guthrie has a very nice &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx"&gt;series of posts&lt;/a&gt; that you don't want to miss out.&lt;br /&gt;&lt;br /&gt;Another new topic, (at least for me) was Synchronization services. Maybe it's because I've never used it, but questions about Synchronization Services were by far the most difficult for me! You can find &lt;a href="http://www.syncguru.com/Projects.aspx"&gt;here&lt;/a&gt; a bunch of demos for the Synchronization framework that you might find useful.&lt;br /&gt;&lt;br /&gt;The last but not the least is the Entity Framework which is still in beta... That's one of the disadvantages of taking beta exams, you are sometimes supposed to have knowledge and experience in technologies that haven't been available long enough... I won't complain though, beta exams do have some advantages (Did I mention that they are free?:)) You can find some code samples for EF Beta 3 version in &lt;a href="http://www.codeplex.com/adonetsamples/"&gt;CodePlex&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The beta period for this exam and ASP.NET exam have been extended until the 5th of May, so if you haven't sat for it yet and you want to take it, hurry up and check &lt;a href="http://blogs.msdn.com/gerryo/archive/2008/04/02/asp-net-and-ado-net-beta-exams-extended.aspx"&gt;Gerry's certification blog&lt;/a&gt;!</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/9177220554612219265/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=9177220554612219265" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/9177220554612219265?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/9177220554612219265?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/327405825/adonet-35-certification-exam.html" title="ADO.NET 3.5 Certification exam" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/04/adonet-35-certification-exam.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUGR3wzeip7ImA9WxZaGUo.&quot;"><id>tag:blogger.com,1999:blog-5608490812663757705.post-8103364054951074410</id><published>2008-04-28T19:37:00.000+02:00</published><updated>2008-05-05T10:47:06.282+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-05T10:47:06.282+02:00</app:edited><title>Welcome to Javi's tech blog!</title><content type="html">So here I am, I've finally decided to have my own technical blog! I've always been very reluctant to start blogging as I’m the kind of tech guy that would rather write code than explain things in a piece of paper or write documentation in general (I'm even very fond of tools like &lt;a href="http://www.roland-weigelt.de/ghostdoc/"&gt;GhostDoc&lt;/a&gt; that help you to make the task of commenting code a bit less tough... too lazy I am I must admit, too bad...)&lt;br /&gt;&lt;br /&gt;I hope then that having a blog will help me to look at the task of writing documentation and posts in a different way, more as fun and less as a burden, and besides it’ll force me to keep up to date to the latest technologies, so overall it does sound like a good idea, doesn’t it? And, on top of that, if anybody finds my posts useful, that'd be great!!&lt;br /&gt;&lt;br /&gt;So as long as I can find some spare time and I have something to say, I’ll be blogging about .NET and related technologies such as ASP.NET, LINQ, WCF, Ajax…&lt;br /&gt;&lt;br /&gt;I hope that you'll be around to check wether this experiment works out or not!&lt;br /&gt;&lt;br /&gt;Javi</content><link rel="replies" type="application/atom+xml" href="http://javicrespotech.blogspot.com/feeds/8103364054951074410/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5608490812663757705&amp;postID=8103364054951074410" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/8103364054951074410?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5608490812663757705/posts/default/8103364054951074410?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/JavisTechnicalBlog/~3/327405826/welcome-to-javis-tech-blog.html" title="Welcome to Javi's tech blog!" /><author><name>Javi</name><uri>http://www.blogger.com/profile/11872722615399930636</uri><email>noreply@blogger.com</email></author><feedburner:origLink>http://javicrespotech.blogspot.com/2008/04/welcome-to-javis-tech-blog.html</feedburner:origLink></entry></feed>
