<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>igorbrejc.net &#187; web services</title>
	<atom:link href="http://igorbrejc.net/category/development/web-services/feed" rel="self" type="application/rss+xml" />
	<link>http://igorbrejc.net</link>
	<description>Just another developer's weblog</description>
	<lastBuildDate>Sun, 12 Feb 2012 06:47:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>C#: Service Caching Proxies With The A Little Help From Some Functional Code</title>
		<link>http://igorbrejc.net/development/c/c-service-caching-proxies-with-the-a-little-help-from-some-functional-code</link>
		<comments>http://igorbrejc.net/development/c/c-service-caching-proxies-with-the-a-little-help-from-some-functional-code#comments</comments>
		<pubDate>Tue, 27 Oct 2009 13:27:26 +0000</pubDate>
		<dc:creator>breki</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[IoC]]></category>
		<category><![CDATA[snippets]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://igorbrejc.net/development/c/c-service-caching-proxies-with-the-a-little-help-from-some-functional-code</guid>
		<description><![CDATA[On a current project we&#8217;re working on in our company, we are developing a web application which accesses the back-end through some web services. Nothing special really, except that certain web services provide pretty static information like lookup tables, which don&#8217;t change very often, so it&#8217;s not really necessary to refetch them all the time. [...]]]></description>
			<content:encoded><![CDATA[<p>On a current project we&#8217;re working on in our company, we are developing a web application which accesses the back-end through some web services. Nothing special really, except that certain web services provide pretty static information like lookup tables, which don&#8217;t change very often, so it&#8217;s not really necessary to refetch them all the time.</p>

<p>Since we are heavily relying on the dependency injection and all the back-end services are exposed through C# interfaces, it wasn&#8217;t really hard to develop a new implementation of such an interface which calls the back-end service and then caches the results in the HTTP cache to be used by any subsequent calls.</p>

<p>Here&#8217;s a simple example of a service interface:</p>

<div><pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">interface</span> IBackendService
{
    List&lt;<span style="color: #0000ff">string&gt;</span> ListSomeStrings(<span style="color: #0000ff">string</span> parameter1, int parameter2);
}</pre></div>

<p>I won&#8217;t bore you with an implementation of this, since it&#8217;s really a dumb one. What&#8217;s interesting is how the cached implementation looks like:</p>

<div><pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> BackendServiceCachingProxy : CachingProxyBase&lt;IBackendService&gt;, IBackendService
{
    <span style="color: #0000ff">public</span> BackendServiceCachingProxy(
        IBackendService wrappedService, 
        Cache cache,
        TimeSpan slidingCacheExpiration)
        : <span style="color: #0000ff">base</span>(wrappedService, cache, slidingCacheExpiration)
    {
    }

    <span style="color: #0000ff">public</span> List&lt;<span style="color: #0000ff">string</span>&gt; ListSomeStrings(<span style="color: #0000ff">string</span> parameter1, <span style="color: #0000ff">int</span> parameter2)
    {
        <span style="color: #0000ff">return</span> CallServiceMethod&lt;<span style="color: #0000ff">string</span>&gt;(
            () =&gt; ConstructCacheKey(<span style="color: #006080">"SomeStrings"</span>, parameter1, parameter2),
            s =&gt; s.ListSomeStrings(parameter1, parameter2));
    }
}</pre></div>

<p>Our caching wrapper inherits from a base class <strong>CachingProxyBase</strong>. Before showing you the code for CachingProxyBase, let me just quickly explain what the <strong>BackendServiceCachingProxy</strong> code does.</p>

<p>We&#8217;re using HTTP cache, so we have to supply it to the class in the constructor. We also specify how long the cache should be valid (<strong>slidingCacheExpiration </strong>parameter). </p>

<p>Each service method in the caching wrapper now uses <strong>CallServiceMethod</strong> method to implement the cached service method calls. You specify two parameters:</p>

<ol>
<li>A function delegate for constructing the cache key. This key should be unique for each unique combination of method&#8217;s input parameters. The CachingProxyBase offers a helper method <strong>ConstructCacheKey </strong>to help you with this task.</li>
<li>A function delegate for calling the method on the service. This delegate will be used for calling the actual service implementation which will contact the back-end.</li></ol>

<h3>&nbsp;</h3>

<h3>CachingProxyBase</h3>

<p>And now the implementation of the CachingProxyBase:</p>

<div><pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">abstract</span> <span style="color: #0000ff">class</span> CachingProxyBase&lt;TService&gt;
{
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> ExpireAllCachedData()
    {
        <span style="color: #0000ff">foreach</span> (System.Collections.DictionaryEntry entry <span style="color: #0000ff">in</span> cache)
            cache.Remove(entry.Key.ToString());
    }

    <span style="color: #0000ff">protected</span> CachingProxyBase(
        TService wrappedService,
        Cache cache,
        TimeSpan slidingCacheExpiration)
    {
        <span style="color: #0000ff">this</span>.wrappedService = wrappedService;
        <span style="color: #0000ff">this</span>.cache = cache;
        <span style="color: #0000ff">this</span>.slidingCacheExpiration = slidingCacheExpiration;
    }

    <span style="color: #0000ff">protected</span> Cache Cache
    {
        get { <span style="color: #0000ff">return</span> cache; }
    }

    <span style="color: #0000ff">protected</span> TimeSpan SlidingCacheExpiration
    {
        get { <span style="color: #0000ff">return</span> slidingCacheExpiration; }
    }

    <span style="color: #0000ff">protected</span> TService WrappedService
    {
        get { <span style="color: #0000ff">return</span> wrappedService; }
    }

    <span style="color: #0000ff">protected</span> TValue CallServiceMethod&lt;TValue&gt;(
        Func&lt;<span style="color: #0000ff">string</span>&gt; constructCacheKeyFunc,
        Func&lt;TService, TValue&gt; serviceMethodFunc)
        <span style="color: #0000ff">where</span> TValue : <span style="color: #0000ff">class</span>
    {
        <span style="color: #0000ff">string</span> cacheKey = constructCacheKeyFunc();

        TValue cachedValue = GetCachedValue&lt;TValue&gt;(cacheKey);

        <span style="color: #0000ff">if</span> (cachedValue == <span style="color: #0000ff">null</span>)
        {
            cachedValue = serviceMethodFunc(WrappedService);
            CacheValue(cacheKey, cachedValue);
        }

        <span style="color: #0000ff">return</span> cachedValue;
    }

    <span style="color: #0000ff">protected</span> <span style="color: #0000ff">string</span> ConstructCacheKey(
        <span style="color: #0000ff">string</span> function, 
        <span style="color: #0000ff">string</span> environmentId, 
        <span style="color: #0000ff">params</span> <span style="color: #0000ff">object</span>[] args)
    {
        StringBuilder cacheKeyBuilder = <span style="color: #0000ff">new</span> StringBuilder();
        cacheKeyBuilder.AppendFormat(
            CultureInfo.InvariantCulture,
            <span style="color: #006080">"Proxy-{0}-{1}"</span>,
            function,
            environmentId);

        <span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">object</span> arg <span style="color: #0000ff">in</span> args)
            cacheKeyBuilder.AppendFormat(CultureInfo.InvariantCulture, <span style="color: #006080">"-{0}"</span>, arg);

        <span style="color: #0000ff">return</span> cacheKeyBuilder.ToString();
    }

    <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> CacheValue(<span style="color: #0000ff">string</span> cacheKey, <span style="color: #0000ff">object</span> <span style="color: #0000ff">value</span>)
    {
        Cache.Insert(
            cacheKey,
            <span style="color: #0000ff">value</span>,
            <span style="color: #0000ff">null</span>,
            Cache.NoAbsoluteExpiration,
            SlidingCacheExpiration);
    }

    [SuppressMessage(<span style="color: #006080">"Microsoft.Design"</span>, <span style="color: #006080">"CA1004:GenericMethodsShouldProvideTypeParameter"</span>)]
    <span style="color: #0000ff">private</span> T GetCachedValue&lt;T&gt;(<span style="color: #0000ff">string</span> cacheKey) 
    {
        <span style="color: #0000ff">return</span> (T)cache.Get(cacheKey);
    }

    <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> TService wrappedService;
    <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> Cache cache;
    <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> TimeSpan slidingCacheExpiration;
}</pre></div>

<p><strong>TService</strong> is a generic parameter representing the service interface the proxy is enhancing with the caching. I think the code is pretty self-explanatory. The <strong>ExpireAllCachedData</strong> method is exposed to be used in unit tests to make sure the cache is empty before doing any work.</p>

<h3>Using It With Windsor Castle</h3>

<p>I&#8217;ve made a helper method for configuring in Windsor Castle a specific back-end service with or without caching:</p>

<div><pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">[SuppressMessage(<span style="color: #006080">"Microsoft.Design"</span>, <span style="color: #006080">"CA1004:GenericMethodsShouldProvideTypeParameter"</span>)]
<span style="color: #0000ff">protected</span> <span style="color: #0000ff">void</span> RegisterServiceWithOptionalCache&lt;TService, TImplementation, TCachedImplementation&gt;(
    IWindsorContainer container,
    TimeSpan slidingCacheExpiration)
    <span style="color: #0000ff">where</span> TImplementation : TService
    <span style="color: #0000ff">where</span> TCachedImplementation : TService
{
    <span style="color: #0000ff">string</span> serviceName = <span style="color: #0000ff">typeof</span>(TService).Name;

    <span style="color: #0000ff">if</span> (IsCachingUsed)
    {
        container.Register(
            Component.For&lt;TService&gt;().ImplementedBy&lt;TCachedImplementation&gt;()
                .ServiceOverrides(ServiceOverride.ForKey(<span style="color: #006080">"wrappedService"</span>).Eq(serviceName))
                .Parameters(Parameter.ForKey(<span style="color: #006080">"slidingCacheExpiration"</span>).Eq(slidingCacheExpiration.ToString())));

        <span style="color: #0000ff">if</span> (log.IsDebugEnabled)
            log.DebugFormat(<span style="color: #006080">"Registered {0}"</span>, <span style="color: #0000ff">typeof</span>(TCachedImplementation).Name);
    }

    container.Register(
        Component.For&lt;TService&gt;().ImplementedBy&lt;TImplementation&gt;()
            .Named(serviceName));            
}</pre></div>

<h3>&nbsp;</h3>

<h3>Conclusion</h3>

<p>There are probably more elegant ways of doing this (probably using Windsor&#8217;s interceptors and reflection), but I think this code does its job well if you have a small number of service methods to cover.</p>
]]></content:encoded>
			<wfw:commentRss>http://igorbrejc.net/development/c/c-service-caching-proxies-with-the-a-little-help-from-some-functional-code/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
	</item>
		<item>
		<title>Friday Goodies &#8211; 08. February</title>
		<link>http://igorbrejc.net/gps/friday-goodies-08-february</link>
		<comments>http://igorbrejc.net/gps/friday-goodies-08-february#comments</comments>
		<pubDate>Fri, 08 Feb 2008 07:58:25 +0000</pubDate>
		<dc:creator>breki</dc:creator>
				<category><![CDATA[GPS]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://igorbrejc.net/gps/friday-goodies-08-february</guid>
		<description><![CDATA[Development 101 Design Patterns &#38; Tips for Developers Web Services Web Service Interoperability? Not from where I sit&#8230; .NET Development MS Deploy &#8211; New IIS Web Deployment Tool StaMa State Machine Controller Library SVNManagerLib &#8211; kernel type library that can be used by .NET Web Services, Remoting, and ASP.NET for remotely administering Subversion symbolware-aima &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Development</p>

<ul>
    <li><a href="http://sourcemaking.com/design-patterns-and-tips">101 Design Patterns &amp; Tips for Developers</a></li>
</ul>

<p>Web Services</p>

<ul>
    <li><a href="http://west-wind.com/WebLog/posts/242929.aspx" style="text-decoration: none">Web Service Interoperability? Not from where I sit&#8230;</a></li>
</ul>

<p>.NET Development</p>

<ul>
    <li><a href="http://www.hanselman.com/blog/MSDeployNewIISWebDeploymentTool.aspx" class="TitleLinkStyle" rel="bookmark">MS Deploy &#8211; New IIS Web Deployment Tool</a></li>
    <li><a href="http://www.codeplex.com/StaMa" id="ctl00_ctl00_WideContent_ProjectTitleControl1_ProjectTitleLink" class="NoUnderline"><span id="ctl00_ctl00_WideContent_ProjectTitleControl1_TitleLabel">StaMa State Machine Controller Library</span></a></li>
    <li><a href="http://www.codeplex.com/svnmanagerlib" id="ctl00_ctl00_WideContent_ProjectTitleControl1_ProjectTitleLink" class="NoUnderline"><span id="ctl00_ctl00_WideContent_ProjectTitleControl1_TitleLabel">SVNManagerLib</span></a> &#8211; <span id="ctl00_ctl00_Content_TabContentPanel_Content_wikiSourceLabel">kernel type library that can be used by .NET Web Services, Remoting, and ASP.NET for remotely administering Subversion</span></li>
    <li><span id="ctl00_ctl00_Content_TabContentPanel_Content_wikiSourceLabel"><a href="http://code.google.com/p/symbolware-aima/">symbolware-aima</a></span> &#8211; C# implementation of algorithms from <a href="http://www.norvig.com/" rel="nofollow">Norvig</a> and <a href="http://www.cs.berkeley.edu/%7Erussell/" rel="nofollow">Russell</a>&#8216;s &#8220;Artificial Intelligence &#8211; A Modern Approach&#8221;</li>
</ul>

<p>VisualStudio</p>

<ul>
    <li><a href="http://www.hanselman.com/blog/VisualStudioProgrammerThemesGallery.aspx" class="TitleLinkStyle" rel="bookmark">Visual Studio Programmer Themes Gallery</a></li>
</ul>

<p><a href="http://aima.cs.berkeley.edu/" rel="nofollow"></a>GPS</p>

<ul>
    <li><a href="http://freegeographytools.com/2008/improving-position-measurement-accuracy-in-consumer-grade-gps-receivers-part-ii" rel="bookmark" title="Permanent Link to ">Improving Position Measurement Accuracy In Consumer-Grade GPS Receivers &#8211; Part II</a></li>
</ul>

<p>Misc</p>

<ul>
    <li><a href="http://www.youtube.com/watch?v=2SgjccK-rvM"><span>Marvão, Portugal 3D in Google Earth</span></a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://igorbrejc.net/gps/friday-goodies-08-february/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
	</item>
		<item>
		<title>Generating WSDL documentation as part of the NAnt build</title>
		<link>http://igorbrejc.net/development/continuous-integration/generating-wsdl-documentation-as-part-of-the-nant-build</link>
		<comments>http://igorbrejc.net/development/continuous-integration/generating-wsdl-documentation-as-part-of-the-nant-build#comments</comments>
		<pubDate>Thu, 31 Jan 2008 07:56:54 +0000</pubDate>
		<dc:creator>breki</dc:creator>
				<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[NAnt]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://igorbrejc.net/development/continuous-integration/generating-wsdl-documentation-as-part-of-the-nant-build</guid>
		<description><![CDATA[WSDLs are not very readable, so I wanted to have some sort of developer-friendly documentation for web services as part of our CI build. I found a simple but effective solution: WSDL viewer (by Tomi Vanek), which is an XSLT transformation file that produces nice HTML documentation. I had to create a custom NAnt task [...]]]></description>
			<content:encoded><![CDATA[<p>WSDLs are not very readable, so I wanted to have some sort of developer-friendly documentation for web services as part of our CI build. I found a simple but effective solution: <a href="http://tomi.vanek.sk/index.php?page=wsdl-viewer">WSDL viewer</a> (by Tomi Vanek), which is an XSLT transformation file that produces nice HTML documentation.</p>

<p>I had to create a custom NAnt task for XSLT transformations since <strong>&lt;style&gt;</strong> task failed when I tried to do transformations using the WSDL viewer XSLT (it was complaining about some XML elements not being declared):</p>

<div class="dean_ch" style="white-space: wrap;"><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;script</span> <span class="re0">language</span>=<span class="st0">&quot;C#&quot;</span> <span class="re0">prefix</span>=<span class="st0">&quot;Brejc.NAntTasks.&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;code<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;![CDATA[</span><br />
<span class="sc2"> &nbsp; &nbsp;[TaskName(&quot;xslt&quot;)]</span><br />
<span class="sc2"> &nbsp; &nbsp;public class XsltTask : Task</span><br />
<span class="sc2"> &nbsp; &nbsp;{</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;[TaskAttribute (&quot;inputfile&quot;, Required = true)]</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;public string InputFile</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return inputFile; }</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { inputFile = value; }</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;[TaskAttribute (&quot;outputfile&quot;, Required = true)]</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;public string OutputFile</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return outputFile; }</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { outputFile = value; }</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;[TaskAttribute (&quot;xsltfile&quot;, Required = true)]</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;public string XsltFile</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get { return xsltFile; }</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set { xsltFile = value; }</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;protected override void ExecuteTask ()</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;XsltSettings xsltSettings = new XsltSettings (true, true);</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;XmlDocument xsltDoc = new XmlDocument();</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xsltDoc.Load (xsltFile);</span><br />
<br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;XmlUrlResolver resolver = new XmlUrlResolver ();</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;XslCompiledTransform transform = new XslCompiledTransform (true);</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;transform.Load (xsltDoc, xsltSettings, resolver);</span><br />
<br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;using (Stream inputStream = File.Open (inputFile, FileMode.Open, FileAccess.Read))</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;XmlReader reader = XmlReader.Create (inputStream);</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;using (XmlWriter writer = XmlWriter.Create (outputFile))</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;transform.Transform (reader, writer);</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;}</span><br />
<br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;private string inputFile;</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;private string outputFile;</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp;private string xsltFile;</span><br />
<span class="sc2"> &nbsp; &nbsp;}</span><br />
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;]]&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/code<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;references<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;include</span> <span class="re0">name</span>=<span class="st0">&quot;System.Xml.dll&quot;</span><span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/include<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/references<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;imports<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;import</span> <span class="re0">namespace</span>=<span class="st0">&quot;System.IO&quot;</span><span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/import<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;import</span> <span class="re0">namespace</span>=<span class="st0">&quot;System.Xml&quot;</span><span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/import<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;import</span> <span class="re0">namespace</span>=<span class="st0">&quot;System.Xml.Xsl&quot;</span><span class="re2">&gt;</span></span><span class="sc3"><span class="re1">&lt;/import<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/imports<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/script<span class="re2">&gt;</span></span></span></div>

<p>Now all you need is to use this task to create the documentation:</p>

<div class="dean_ch" style="white-space: wrap;"><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;docs.wsdl&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;generates wsdl based on the existing web services&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;mkdir</span> <span class="re0">dir</span>=<span class="st0">&quot;doc\wsdl&quot;</span> <span class="re0">unless</span>=<span class="st0">&quot;${directory::exists(&#8216;doc\wsdl&#8217;)}&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;xslt</span> <span class="re0">inputfile</span>=<span class="st0">&quot;SomeWebService.wsdl&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; outputfile=&quot;doc\wsdl\SomeWebService.html&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xsltfile=&quot;lib\WsdlViewer\wsdl-viewer.xsl&quot;/&gt;<br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/xslt<span class="re2">&gt;</span></span></span><br />
<span class="sc3"><span class="re1">&lt;/mkdir<span class="re2">&gt;</span></span></span><span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span></div>
]]></content:encoded>
			<wfw:commentRss>http://igorbrejc.net/development/continuous-integration/generating-wsdl-documentation-as-part-of-the-nant-build/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
	</item>
	</channel>
</rss>

