<feed version="0.3" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns="http://purl.org/atom/ns#" xml:lang="en-US"><title>Christian Weyer: Smells like service spirit</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/default.aspx" /><tagline type="text/html">What's first?</tagline><id>http://blogs.thinktecture.com/cweyer/default.aspx</id><author><url>http://blogs.thinktecture.com/cweyer/default.aspx</url></author><generator url="http://communityserver.org" version="1.1.0.50615">Community Server</generator><modified>2009-05-08T08:37:00Z</modified><entry><title>Generating async WCF OperationContract signatures with a T4 template</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/06/24/415372.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415372</id><created>2009-06-24T10:01:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;
From time to time it happens that people want to use the async programming model in WCF based on the &lt;a href="http://www.danrigsby.com/blog/index.php/2008/03/26/async-operations-in-wcf-iasyncresult-model-server-side/"&gt;IAsyncResult approach&lt;/a&gt;
- either on the client or the service side. Writing all the
asynchronous operation contract signatures is quite a tedious and
error-prone task. Given this fact, design-time code generation with a
T4 template may come in very handy for this purpose.&lt;br&gt;
The following is my first try to create such a &lt;a href="http://visualstudiomagazine.com/articles/2009/05/01/visual-studios-t4-code-generation.aspx"&gt;T4 template&lt;/a&gt;
and it seems to work for the scenarios I need it for. Please refer to
code below to see how to use the template: it is easy and
straight-forward.&lt;br&gt;
&lt;br&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;lt;# &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;/*&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; Copyright (c) 2009, thinktecture (http://www.thinktecture.com).&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; All rights reserved.&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; Permission is hereby granted to use this software, for both commercial &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; and non-commercial purposes, without limitations and free of charge.&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; Permission is hereby granted to copy and distribute the software for &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; non-commercial purposes. A commercial distribution is NOT allowed without&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; prior written permission of the authors.&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; This software is supplied "AS IS". The authors disclaim all warranties, &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; expressed or implied, including, without limitation, the warranties of &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; merchantability and of fitness for any purpose. The authors assume no&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; liability for direct, indirect, incidental, special, exemplary, or&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; consequential damages, which may result from the use of this software,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; even if advised of the possibility of such damage.&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;*/&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;#&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;lt;#@ template debug="true" hostspecific="true" #&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;lt;#@ output extension="cs" #&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;lt;#@ assembly name="EnvDTE" #&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;lt;#@ import namespace="EnvDTE" #&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;lt;#@ import namespace="System.Diagnostics" #&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;lt;#@ import namespace="System.Collections.Generic" #&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;lt;#&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New; font-weight: bold;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // USAGE:&lt;/span&gt;&lt;br style="font-family: Courier New; font-weight: bold;"&gt;
&lt;span style="font-family: Courier New; font-weight: bold;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 1. Drop this file into your VS project&lt;/span&gt;&lt;br style="font-family: Courier New; font-weight: bold;"&gt;
&lt;span style="font-family: Courier New; font-weight: bold;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 2. Rename this file to match this pattern: {YOUR_SERVICECONTRACT_FILE}Async.tt&lt;/span&gt;&lt;br style="font-family: Courier New; font-weight: bold;"&gt;
&lt;span style="font-family: Courier New; font-weight: bold;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 3. The async version of your original service contract gets generated as &lt;/span&gt;&lt;br style="font-family: Courier New; font-weight: bold;"&gt;
&lt;span style="font-family: Courier New; font-weight: bold;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; {YOUR_SERVICECONTRACT_FILE}Async.cs&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EnvDTE.DTE dte = GetEnvDTE();&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string sourceFileName = dte.Solution.FindProjectItem(Host.TemplateFile).Name;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sourceFileName = sourceFileName.Replace("Async.tt", ".cs");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProjectItem enumProjectItem = dte.Solution.FindProjectItem(sourceFileName);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileCodeModel codeModel = enumProjectItem.FileCodeModel;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CodeNamespace codeNamespace = FindNamespace(codeModel.CodeElements);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CodeInterface codeInterface = FindInterface(codeModel.CodeElements);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;CodeFunction&amp;gt; codeFunctions = FindMethods(codeInterface.Children);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //System.Diagnostics.Debugger.Break();&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;#&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;using System;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;using System.ServiceModel;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;namespace &amp;lt;#= codeNamespace.Name #&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;{&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ServiceContract]&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public interface &amp;lt;#= codeInterface.Name #&amp;gt;Channel : &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;#= codeInterface.Name#&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;#&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; PushIndent("&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; int methodCount = 0;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (CodeFunction method in codeFunctions)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(methodCount &amp;gt; 0)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine(String.Empty);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine(String.Empty);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteAsyncOperationContract(method);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine(string.Empty);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; methodCount ++;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ClearIndent();&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;}&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;lt;#+&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void WriteAsyncOperationContract(CodeFunction method)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; string operationContractValue = TryGetOperationContractValue(method);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine("[OperationContract(");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(String.IsNullOrEmpty(operationContractValue))&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write("&amp;nbsp;&amp;nbsp;&amp;nbsp; Action = \"");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write(method.Name + "\",");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine(String.Empty);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write("&amp;nbsp;&amp;nbsp;&amp;nbsp; ReplyAction = \"");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write(method.Name + "Reply\",");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine(String.Empty);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ClearIndent();&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine("&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; " + operationContractValue + ",");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; PushIndent("&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine("&amp;nbsp;&amp;nbsp;&amp;nbsp; AsyncPattern = true)]");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write("IAsyncResult Begin");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write(method.Name);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write("(");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foreach(CodeElement element in method.Parameters)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; int count = 0;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CodeParameter parameter = element as CodeParameter;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (parameter != null)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write(parameter.Type.AsString + " ");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write(parameter.Name);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(count &amp;lt; method.Parameters.Count)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write(", ");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; count++;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write("AsyncCallback callback, object asyncState);");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine(String.Empty);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine(String.Empty);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write(method.Type.AsString + " ");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write("End");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write(method.Name);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Write("(IAsyncResult result);");&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string TryGetOperationContractValue(CodeFunction method)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; string attributeValue = String.Empty;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foreach(CodeElement attributeElement in method.Attributes)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CodeAttribute attribute = attributeElement as CodeAttribute;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(attribute != null)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(attribute.Name == "OperationContract" || attribute.Name == "OperationContractAttribute")&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; attributeValue = attribute.Value;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return attributeValue;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private CodeNamespace FindNamespace(CodeElements elements)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (CodeElement element in elements)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CodeNamespace ns = element as CodeNamespace;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (ns != null)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return ns;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private CodeInterface FindInterface(CodeElements elements)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (CodeElement element in elements)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CodeInterface codeInterface = element as CodeInterface;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (codeInterface != null)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return codeInterface;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; codeInterface = FindInterface(element.Children);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (codeInterface != null)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return codeInterface;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private List&amp;lt;CodeFunction&amp;gt; FindMethods(CodeElements elements)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;CodeFunction&amp;gt; methods = new List&amp;lt;CodeFunction&amp;gt;();&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (CodeElement element in elements)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CodeFunction method = element as CodeFunction;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (method != null)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; methods.Add(method);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return methods;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private EnvDTE.DTE GetEnvDTE()&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; IServiceProvider hostServiceProvider = (IServiceProvider)Host;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (hostServiceProvider == null)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception("Host property returned unexpected value (null)");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (dte == null)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception("Unable to retrieve EnvDTE.DTE");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return dte;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;
&lt;span style="font-family: Courier New;"&gt;#&amp;gt;&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
This is it - T4 programming reminds me of my very old days as a classical COM and ASP programmer... :)&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415372" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415372</wfw:commentRss></entry><entry><title>Custom TraceListener writing trace messages to the .NET Services Service Bus</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/06/24/415371.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415371</id><created>2009-06-24T08:24:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;&lt;a href="http://www.leastprivilege.com"&gt;Dominick&lt;/a&gt; challenged me the other day...&lt;br&gt;For being able to better log information, warning and error messages in a truly distributed development, testing and operation environment, I built a sample custom &lt;a href="http://msdn.microsoft.com/en-us/library/4y5y10s7.aspx"&gt;TraceListener&lt;/a&gt; which leverages the &lt;a href="http://www.microsoft.com/azure/servicebus.mspx"&gt;Service Bus&lt;/a&gt; to pump tracing messages into the cloud.&lt;br&gt;&lt;br&gt;Currently I am using the message-buffer-based volatile queuing mechanism in the Service Bus, but will move on to the Queue features introduced in the March 2009 bits soon.&lt;br&gt;&lt;br&gt;There is a very simple ServiceContract I am using:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;[ServiceContract(ConfigurationName = "Thinktecture.ServiceBusTraceListener")]&lt;br&gt;public interface IMessageTracing&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;[OperationContract(IsOneWay = true)]&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;void WriteMessage(string message);&lt;br&gt;}&lt;br&gt;&lt;/font&gt;&lt;br&gt;All the magic is done in my custom TraceListener implementation. Here is a snippet of the relevant boilerplate code:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;public class ServiceBusTraceListener : TraceListener&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ServiceBusTraceListener()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base("Thinktecture.ServiceBusTraceListener")&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CreateInMemoryQueue();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SpawnWorkerThread();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void Write(string message)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine(message);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void WriteLine(string message)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; traceMessagesQueue.Enqueue(message);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;}&lt;/font&gt;&lt;br&gt;&lt;br&gt;This simple implementation uses a &lt;a href="http://blogs.msdn.com/jaredpar/archive/2009/02/16/a-more-usable-thread-safe-collection.aspx"&gt;thread-safe in-memory queue&lt;/a&gt; data structure which is filled from within the TraceListener's WriteLine method. On 'the other side' of the queue there is a consuming thread which reads the messages from the queue (the in-memory one) and sends them to the Service Bus via a &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.neteventrelaybinding.aspx"&gt;NetEventRelayBinding&lt;/a&gt;-enabled channel.&lt;br&gt;The background thread doing the Service Bus communication picks up all relevant WCF configuration from the config file (convention-based).&lt;br&gt;&lt;br&gt;&lt;i&gt;&lt;a href="http://static.thinktecture.com/christianweyer/ServiceBusTraceListener.zip"&gt;Download&lt;/a&gt; the sample solution.&lt;/i&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415371" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415371</wfw:commentRss></entry><entry><title>thinktecture Security Token Service Starter Kit - or: &amp;quot;Look ma: even *I* can have a STS!&amp;quot;</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/26/415363.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415363</id><created>2009-05-26T07:01:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;We are happy to announce the &lt;a href="http://startersts.codeplex.com/"&gt;thinktecture Security Token Service (STS) Starter Kit&lt;/a&gt;. It shows how to build a basic yet powerful STS based on Geneva Framework (Beta 2) which integrates with all the nice and powerful ASP.NET-isms like membership, roles and profiles.&lt;br&gt;
&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/STS_StarterKit_1.png" alt="thinktecture STS Starter Kit"&gt;
&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/STS_StarterKit_IIS.png" alt="thinktecture STS Starter Kit IIS config"&gt;
&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/STS_StarterKit_2.png" alt="thinktecture STS Starter Kit"&gt;
&lt;br&gt;
&lt;br&gt;The heart of the STS is configured with a simple web.config entry like this:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;starterSTS siteName="thinktecture Security Token Service Starter Sample"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; issuerUri="http://sample.thinktecture.com/trust"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; claimsBaseUri="http://sample.thinktecture.com/claims"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; requireEncryption="false"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; requireSSL="false"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; enableMessageWSTrust="true"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; enableMixedWSTrust="false" /&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;Read &lt;a href="http://www.leastprivilege.com/ThinktectureSecurityTokenServiceStarterKit.aspx"&gt;Dominick's blog post&lt;/a&gt; for more details and please make sure to watch the &lt;a href="http://www.leastprivilege.com/startersts/StarterSTS_SetupAndOverview.wmv"&gt;Setup &amp;amp; Overview screencast&lt;/a&gt;.&lt;br&gt;Any feedback is highly appreciated!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415363" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415363</wfw:commentRss></entry><entry><title>Geneva-based WS-Federation metadata document generation wizard (or: &amp;quot;Oops, I did it again!&amp;quot;)</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/22/415362.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415362</id><created>2009-05-22T11:24:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;Starting with Beta 2 of the Geneva Framework there is nice support of metadata-driven behavior and code generation. We (&lt;a href="http://www.leastprivilege.com"&gt;Mr. Security himself&lt;/a&gt; and me) came across some situations where one wants to generate manually the WS-Federation metadata document and then use this XML e.g. with the &lt;i&gt;fedutil.exe&lt;/i&gt; tool or the integrated Geneva tooling inside Visual Studio.&lt;br&gt;I couldn't resist and build a wizard which helps generating the metadata document... sorry :) &lt;a href="http://www.thinktecture.com/WSCF/"&gt;Feels like Groundhog Day&lt;/a&gt;.&lt;br&gt;&lt;br&gt;Here we go.&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/FedMDGen_Page1.png" alt="WS-Federation Metadata document generator - page 1"&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/FedMDGen_Page2.png" alt="WS-Federation Metadata document generator - page 2"&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/FedMDGen_Page3.png" alt="WS-Federation Metadata document generator - page 3"&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/FedMDGen_Page4.png" alt="WS-Federation Metadata document generator - page 4"&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/FedMDGen_Page5.png" alt="WS-Federation Metadata document generator - page 5"&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/FedMDGen_Page6.png" alt="WS-Federation Metadata document generator - page 6"&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/FedMDGen_Page7.png" alt="WS-Federation Metadata document generator - page 7"&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/FedMDGen_Page8.png" alt="WS-Federation Metadata document generator - page 8"&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/FedMDGen_Page9.png" alt="WS-Federation Metadata document generator - page 9"&gt;

&lt;br&gt;&lt;br&gt;

&lt;i&gt;Note: I am using the DevExpress wizard control and dependent assemblies. Therefore the size of the ZIP is rather big (too big, IMHO) - sorry.&lt;/i&gt;&lt;br&gt;&lt;br&gt;For whom it may help: &lt;a href="http://static.thinktecture.com/christianweyer/FederationMetadataGenerator_1.0.zip"&gt;Download&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415362" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415362</wfw:commentRss></entry><entry><title>Axum and the CCR: what and how?</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/11/415355.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415355</id><created>2009-05-11T15:33:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;This is copied verbatim from a MSDN Forums post about how &lt;a href="http://blogs.thinktecture.com/cweyer/archive/2009/05/11/415351.aspx"&gt;Axum&lt;/a&gt; uses parts of the &lt;a href="http://msdn.microsoft.com/en-us/library/bb648752.aspx"&gt;CCR&lt;/a&gt;:&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;&lt;i&gt;Here's what we did:&lt;/i&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;1. We took the CCR sources, changed most of the names, slightly refactored the interfaces and added a few things.&lt;/i&gt;&lt;br&gt;&lt;i&gt;2. We built it into Microsoft.Axum.Runtime.dll&lt;/i&gt;&lt;br&gt;&lt;i&gt;3. We built channel ports on top of CCR Ports (renamed OrderedInteractionPoints).&lt;/i&gt;&lt;br&gt;&lt;i&gt;4. We exposed OIP to&amp;nbsp;programmers (see the WebFetcher sample).&lt;/i&gt;&lt;br&gt;&lt;i&gt;5. We built 'async,' 'sync,' and 'const' empty/full storage capabilites on some additions we made to CCR.&lt;/i&gt;&lt;br&gt;&lt;i&gt;6. The 'receive' expression utilizes a Receiver to hook into the source.&lt;/i&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;One
reason for the rename is that in the CTP, you really need to use the
Axum capabilities (data-flow networks, receives, etc.) to program the
local (within-domain) message-passing capabilites, and we didn't want
to create another distribution of the CCR. If you want to use CCR,
please get it separately, as it is not currently safe to use with Axum
unless you go through the language capabilities. It is likewise not
generally safe to create your own threads from within an Axum domain,
and there is no need to.&lt;/i&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/axum/thread/92ad0e6a-a7bb-4bc7-be94-82441614e8ad/"&gt;Source&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415355" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415355</wfw:commentRss></entry><entry><title>Information Card Foundation DACH-Initiative: kein Gremium, sondern eine Plattform</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/11/415354.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415354</id><created>2009-05-11T15:08:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;Wir hoffen, dass sich durch &lt;a href="http://www.informationcard.de/"&gt;diese Initiative&lt;/a&gt; viele Unternehmen inspirieren lassen, Identitäts-Management im Allgemeinen und Authentifizierung mit Information Cards im Speziellen genauer unter die Lupe zu nehmen.&lt;br&gt;&lt;br&gt;&lt;i&gt;&lt;a href="http://www.informationcard.de/sites/default/files/ICF-DACH_Flyer.pdf"&gt;PDF-Flyer in deutsch&lt;/a&gt; als Download.&lt;/i&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;img src="http://static.thinktecture.com/christianweyer/ICF_DACH_1.jpg" alt="ICF DACH Initiative"&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415354" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415354</wfw:commentRss></entry><entry><title>Axum - a service-oriented programming language(?)</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/11/415352.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415352</id><created>2009-05-11T11:56:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;The more I read about &lt;a href="http://blogs.thinktecture.com/cweyer/archive/2009/05/11/415351.aspx"&gt;Axum&lt;/a&gt; and hack the first lines of code, the more I feel there will be something that &lt;i&gt;could&lt;/i&gt; make my life easier.&lt;br&gt;In the past years I tried to advocate the idea of service-orientation (and no: I am *&lt;b&gt;not&lt;/b&gt;* talking about SOA - if you ever attended a session of mine you know that I am more than explicit about this point).&lt;br&gt;&lt;br&gt;I like the idea of explicit boundaries, description via interfaces and contracts and definition of policies for runtime information. It goes that far that I try to follow the service-orientation principles wherever it makes sense (usually being a bit weak on the policies side).&lt;br&gt;Please note that I am not talking about WCF, I am talking about service-orientation. Yes, WCF is quite a nice framework (read: tool) to realize service-oriented systems. But then it is also a communication foundation which means it can be used to accomplish a lot more than the prototypical thinking around service-orientation.&lt;br&gt;&lt;br&gt;Service-orientation is an attitude.&lt;br&gt;&lt;br&gt;Now with &lt;a href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx"&gt;Axum&lt;/a&gt; I can smell service-orientation in my language.&lt;br&gt;&lt;br&gt;In service orientation there are services. In service orientation data is exchanged via channels and messages. In service orientation there are message handlers. In service orientation there are interfaces and contracts to describe the boundary.&lt;br&gt;&lt;br&gt;In Axum there are domains for isolation. In Axum information is passed
via channels and messages. In Axum there are agents for handling
communication (either in a domain or between domains). In Axum there is
schema to describe the exchanged information.&lt;br&gt;
&lt;br&gt;Pure joy (there seem to be more equivalent ideas, but this is good enough for starters).&lt;br&gt;We will see how this all turns out. On one hand, I am still starting to understand Axum. On the other hand, Axum is currently an incubation project, nothing more.&lt;br&gt;&lt;br&gt;&lt;i&gt;P.S.: the last Microsoft incubation project I was working on/with was code-named "Biztalk Services". This is now known as .NET Services as part of the Azure Services Platform...&lt;/i&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;BTW: I am *&lt;b&gt;not&lt;/b&gt;* advocating that every class should be a service (at least there is no concept of a class in Axum ;)).&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415352" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415352</wfw:commentRss></entry><entry><title>I *think* I see the future: Axum (or is it just Erlang for .NET?)</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/11/415351.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415351</id><created>2009-05-11T09:01:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;Holy cow. There have been a lot of announcements recently in the space of parallel programming, language- and tool-wise (just look at what happened at PDC08). And I must admit I could not keep up with researching each and every announcement.&lt;br&gt;&lt;br&gt;I played around a bit the other day (OK, the other year...) with the &lt;a href="http://msdn.microsoft.com/en-us/library/bb648752.aspx"&gt;Concurrency &amp;amp; Coordination Runtime (CCR)&lt;/a&gt; from the Microsoft Robotics team - but I could not really get convinced that this is what we are supposed to do in the future when planning, architecting and writing highly distributed, concurrent applications (or actually algorithms or 'pieces of code'). No, this just feels too clumsy, too much tool- and library-heavy.&lt;br&gt;And no, I did not yet look in depth into the new stuff that .NET 4.0 will bring us. Just a matter of time, I guess.&lt;br&gt;&lt;br&gt;Then, on Friday, I stumbled over something that looks promising: &lt;a href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx"&gt;Axum&lt;/a&gt;.&lt;br&gt;And the more I read about it and the more I play around (it is really just playing, trying to grok, to understand, to learn) the more I *think* this *could* be the future of parallel programming and processing. One nice thing is that Axum builds on top of some of the CCR features, but gives us a language and not a lib and tool feeling.&lt;br&gt;&lt;br&gt;Browsing the web I can already see discussions how Axum relates and compares to Erlang. I not really such a big language expert, but borrowing from a very successful language (which solves exactly the problems it was invented for) is nothing to trash :)&lt;br&gt;&lt;br&gt;Just a note, though.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415351" width="1" height="1"&gt;</content><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415351</wfw:commentRss></entry><entry><title>[What's new in WCF4] Protocol bridging &amp;amp; fault tolerance with the Routing Service - or: &amp;quot;Look ma: Really just one service to talk to!&amp;quot;</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415341.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415341</id><created>2009-05-08T13:33:00Z</created><content type="text/html" mode="escaped">&lt;i&gt;&lt;br&gt;[Note: all the information was gathered based on a close-to-Beta 1
build of .NET Framework 4.0 and Visual Studio 2010. Details may vary
and change]&lt;br&gt;&lt;br&gt;&lt;/i&gt;Let's look at some more features of the &lt;a href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415335.aspx"&gt;new RoutingService in WCF4&lt;/a&gt;.&lt;br&gt;We are going to expose our RoutingService via an basicHttpBinding-based request-reply endpoint:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;service behaviorConfiguration="routingData"&lt;br&gt;&amp;nbsp; name="System.ServiceModel.Routing.RoutingService"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;host&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;baseAddresses&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;add&amp;nbsp; baseAddress="http://localhost:7777/Services/Universal"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/baseAddresses&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/host&amp;gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;endpoint address=""&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; binding="basicHttpBinding"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; name="requestReplyEndpoint"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; contract="System.ServiceModel.Routing.IRequestReplyRouter" /&amp;gt;&lt;br&gt;&amp;lt;/service&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;Then 'internally' we have two business services, HelloService1 and HelloService2 :)&lt;br&gt;One of them is exposed via a basicHttpBinding-based endpoint, the other one uses netTcpBinding.&lt;br&gt;&lt;br&gt;We can now configure our router in such a way that it still accepts incoming messages via basicHttpBinding (actually we just did that and do not need to change anything) but can route messages to the netTcpBinding-based service.&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;client&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;endpoint name="HelloService1"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;address="net.tcp://localhost:7778/Services/Hello"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;binding="netTcpBinding"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;contract="*" /&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;endpoint name="HelloService2"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;address="http://localhost:7777/Services/Hello"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;binding="basicHttpBinding"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;contract="*" /&amp;gt;&lt;br&gt;&amp;lt;/client&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;OK, great.&lt;br&gt;Our routing table looks like this, which means we will always (try to) route to the netTcpBinding-based service.&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;routingTables&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;table name="mainRoutingTable"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;entries&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;add filterName="xPath1" endpointName="HelloService1" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/entries&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/table&amp;gt;&lt;br&gt;&amp;lt;/routingTables&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;But what happens if *** happens?&lt;br&gt;We can specify alternate endpoints which will be called when a CommunicationException or TimeoutException occurs in the RoutingService while calling the original target endpoint.&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;routingTables&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;table name="mainRoutingTable"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;entries&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;add filterName="xPath1" endpointName="HelloService1" alternateEndpoints="endpointsList" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/entries&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/table&amp;gt;&lt;br&gt;&amp;lt;/routingTables&amp;gt;&lt;br&gt;&amp;lt;alternateEndpoints&amp;gt;&lt;br&gt;&amp;lt;list name="endpointsList"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;endpoints&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;add endpointName="HelloService2" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;!--&amp;lt;add endpointName="HelloService3" /&amp;gt;--&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/endpoints&amp;gt;&lt;br&gt;&amp;lt;/list&amp;gt;&lt;br&gt;&amp;lt;/alternateEndpoints&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;We can have as many alternate endpoints as we like, in this sample it is just one active one, namely our HelloService2 which is exposed via a basicHttpBinding endpoint.&lt;br&gt;&lt;br&gt;That's it: protocol bridging &amp;amp; fault tolerance with the Routing Service in WCF4.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415341" width="1" height="1"&gt;</content><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415341</wfw:commentRss></entry><entry><title>[What's new in WCF4] Routing Service - or: &amp;quot;Look ma: Just one service to talk to!&amp;quot;</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415335.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415335</id><created>2009-05-08T11:47:00Z</created><content type="text/html" mode="escaped">&lt;i&gt;&lt;br&gt;[Note: all the information was gathered based on a close-to-Beta 1
build of .NET Framework 4.0 and Visual Studio 2010. Details may vary
and change]&lt;br&gt;&lt;br&gt;&lt;/i&gt;The &lt;a href="http://www.soapatterns.org/intermediate_routing.asp"&gt;Intermediate Routing pattern&lt;/a&gt; is a well understood pattern. Some people apply it to have just one service entry point with a universal contract and then route incoming messages to the appropriate business services.&lt;br&gt;Others use it to determine the path of a message within a system, which means there can be a cascade of routers each responsible for different aspects of routing messages.&lt;br&gt;WCF was always a bit short in this respect. Sure, there are numerous implementations based on WCF 3.x (just Google...), just recently &lt;a href="http://www.leastprivilege.com"&gt;Dominick&lt;/a&gt; and myself implemented something like this for a customer. But there is nothing that came straight in the core platform. This now changes with WCF4.&lt;br&gt;&lt;br&gt;There is a generic routing service in WCF4 which enables routing for diiferent message exchange patterns (MEPs). The responsible class is System.ServiceModel.Routing.RoutingService.&lt;br&gt;&lt;br&gt;&lt;img src="http://static.thinktecture.com/christianweyer/WCF4_RoutingService_1.png" alt="WCF4 Routing Service"&gt;&lt;br&gt;&lt;br&gt;As we can see this service implements four different contracts to fulfill different MEPs and session semantics. If we want to host a routing service we do not need a lot of work, just host it (like this for a self-hosted case):&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;ServiceHost serviceHost = new ServiceHost(typeof(RoutingService));&lt;br&gt;&lt;br&gt;try&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;serviceHost.Open();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Console.WriteLine("WCF Routing Service running..."); &lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Console.WriteLine("Press &amp;lt;ENTER&amp;gt; to terminate router.");&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Console.ReadLine();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;serviceHost.Close();&lt;br&gt;}&lt;br&gt;catch (CommunicationException)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;serviceHost.Abort();&lt;br&gt;}&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;OK, easy.&lt;br&gt;Each of the contracts RoutingService implements represent the universal contract pattern (Message in, Message out, or just Message in for the one-way case). WCF4 always uses the async operation pattern, which totally makes sense as we have bound I/O happening in the routing service:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;[ServiceContract(SessionMode=SessionMode.Allowed)]&lt;br&gt;public interface ISimplexDatagramRouter&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [OperationContract(AsyncPattern=true, IsOneWay=true, Action="*")]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void EndProcessMessage(IAsyncResult result);&lt;br&gt;}&lt;br&gt;&lt;br&gt;[ServiceContract(SessionMode=SessionMode.Required)]&lt;br&gt;public interface ISimplexSessionRouter&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [OperationContract(AsyncPattern=true, IsOneWay=true, Action="*")]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void EndProcessMessage(IAsyncResult result);&lt;br&gt;}&lt;br&gt;&lt;br&gt;[ServiceContract(SessionMode=SessionMode.Allowed)]&lt;br&gt;public interface IRequestReplyRouter&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [OperationContract(AsyncPattern=true, IsOneWay=false, Action="*", ReplyAction="*"), GenericTransactionFlow(TransactionFlowOption.Allowed)]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IAsyncResult BeginProcessRequest(Message message, AsyncCallback callback, object state);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Message EndProcessRequest(IAsyncResult result);&lt;br&gt;}&lt;br&gt;&lt;br&gt;[ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IDuplexRouterCallback))]&lt;br&gt;public interface IDuplexSessionRouter&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [OperationContract(AsyncPattern=true, IsOneWay=true, Action="*"), GenericTransactionFlow(TransactionFlowOption.Allowed)]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void EndProcessMessage(IAsyncResult result);&lt;br&gt;}&lt;br&gt;&lt;/font&gt;&lt;br&gt;&lt;font face="Courier New"&gt;[ServiceContract(SessionMode=SessionMode.Allowed)]&lt;br&gt;internal interface IDuplexRouterCallback&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [OperationContract(AsyncPattern=true, IsOneWay=true, Action="*"), GenericTransactionFlow(TransactionFlowOption.Allowed)]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void EndProcessMessage(IAsyncResult result);&lt;br&gt;}&lt;br&gt;&lt;/font&gt;&lt;br&gt;Pure love :) &lt;br&gt;&lt;br&gt;So, that was for the WCF infrastructure geek - but how do we actually route? What do we route?&lt;br&gt;Enter message filters.&lt;br&gt;The routing service in WCF4 uses message filters in order to route messages. Message filters have always been in WCF since the first version and just now have a prominent role and also got some new filters. This is the list of available message filters:&lt;br&gt;&lt;br&gt;&lt;img src="http://static.thinktecture.com/christianweyer/WCF4_MessageFilters_1.png" alt="WCF4 Message Filters"&gt;&lt;br&gt;&lt;br&gt;For a first rendezvous with routing we will just use the MatchAllMessageFilter. This filter just returns true and does not do any logic in the Match() method and thus is a pass-through filter.&lt;br&gt;Message filter will be used inside entries in a RoutingTable. These entries specify which endpoint to call from the RoutingService when the given MessageFilter returns true. The routing table is configured as a service behavior.&lt;br&gt;Here is a sample config implementing the just explained stuff:&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;configuration&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;system.serviceModel&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;service behaviorConfiguration="routingData"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name="System.ServiceModel.Routing.RoutingService"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;host&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;baseAddresses&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add baseAddress="&lt;b&gt;http://localhost:7777/Services/Universal&lt;/b&gt;"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/baseAddresses&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/host&amp;gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint address="" &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; binding="basicHttpBinding" &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name="requestReplyEndpoint" &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; contract="&lt;b&gt;System.ServiceModel.Routing.IRequestReplyRouter&lt;/b&gt;" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/service&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;behaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceBehaviors&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;behavior name="routingData"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceMetadata httpGetEnabled="True"/&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;routing routingTableName="mainRoutingTable" /&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/behavior&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/serviceBehaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/behaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;client&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint name="HelloService" address="http://localhost:7777/Services/Hello" binding="basicHttpBinding" contract="*" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/client&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;routing&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filters&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filter name="MatchAllFilter" filterType="MatchAll" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/filters&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;routingTables&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;table name="mainRoutingTable"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;entries&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add filterName="MatchAllFilter" endpointName="HelloService" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/entries&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/table&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/routingTables&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/routing&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp; &amp;lt;/system.serviceModel&amp;gt;&lt;br&gt;&amp;lt;/configuration&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;This means we expose an IRequestReplyRouter with basicHttpBinding at http://localhost:7777/Services/Universal to the consumers. As a final target service we just have one service (our beloved HelloService) and its endpoint is defined in the &amp;lt;client&amp;gt; section.&lt;br&gt;Based on the message filter which is referenced through an entry in the routing table the messages being sent to our routing endpoint will be routed through to our HelloService.&lt;br&gt;Admittedly, this sample is not really real-worldish :) But it should give a first understanding of the RoutingService in WCF4.&lt;br&gt;&lt;br&gt;To make the whole picture complete, we will let our client/consumer just talk to the routing endpoint - the client does not know anything about the HelloService (besides the contract of course).&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;configuration&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;system.serviceModel&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;client&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint address="&lt;b&gt;http://localhost:7777/Services/Universal&lt;/b&gt;"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; binding="basicHttpBinding"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; contract="IHelloService" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/client&amp;gt;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp; &amp;lt;/system.serviceModel&amp;gt;&lt;br&gt;&amp;lt;/configuration&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;Please note that until now we just do plain routing in the sense of message dispatching. We can not do message transformations (yet). This should be covered in a future post, though.&lt;br&gt;&lt;br&gt;But let's look at two more message filters, the ActionMessageFilter and the XPathMessageFilter, which both come in very handy for typical routing scenarios.&lt;br&gt;The ActionMessageFilter checks whether a given action value is fulfilled for the incoming message. Likewise, the XPathMessageFilter checks whether a given XPath expression is true for an incoming message. Usually, the XPath filter needs namespace table entries for managing XML namespaces.&lt;br&gt;In order to use either of these filters to route our client messages to the HelloService we can change the filters and routing table configuration like this:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;routing&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;filters&amp;gt;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;!--&amp;lt;filter name="action1" filterType="Action" filterData="http://tempuri.org/IHelloService/SayIt" /&amp;gt;--&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;filter name="xPath1" filterType="XPath" filterData="/s:Envelope/s:Header/wsa:Action = 'http://tempuri.org/IHelloService/SayIt'" /&amp;gt;&lt;br&gt;&lt;/b&gt;&amp;nbsp; &amp;lt;/filters&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;routingTables&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;table name="mainRoutingTable"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;entries&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;!--&amp;lt;add filterName="action1" endpointName="HelloService" /&amp;gt;--&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;add filterName="xPath1" endpointName="HelloService" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/entries&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/table&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;/routingTables&amp;gt;&lt;br&gt;&lt;b&gt;&amp;nbsp; &amp;lt;namespaceTable&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;add prefix="s" namespace="http://schemas.xmlsoap.org/soap/envelope/" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;add prefix="wsa" namespace="http://schemas.microsoft.com/ws/2005/05/addressing/none" /&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;/namespaceTable&amp;gt;&lt;br&gt;&lt;/b&gt;&amp;nbsp; &amp;lt;alternateEndpoints&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp; &amp;lt;/alternateEndpoints&amp;gt;&lt;br&gt;&amp;lt;/routing&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;The two filter configurations are equivalent in their functionailty based on the given filter data values.&lt;br&gt;Pretty straight.forward, IMO.&lt;br&gt;&lt;br&gt;One more thing: if the originally specified endpoint in a routing table entry cannot be reached then the list of alternate endpoints is checked (OK, in our sample it is empty, but you get the idea) and the routing service logic tries to call them.&lt;br&gt;&lt;br&gt;Honestly, I can see a number of customers embracing this new feature (and in this post I was just scratching the surface).&lt;br&gt;&lt;br&gt;OK; that's it for now for a first introduction to the routing capabilities in WCF4.&lt;br&gt;Stay tuned for more.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415335" width="1" height="1"&gt;</content><slash:comments>4</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415335</wfw:commentRss></entry><entry><title>[What's new in WCF4] Discovery announcements - or: &amp;quot;Look ma: I can see when my service goes online or offline!&amp;quot;</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415332.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415332</id><created>2009-05-08T10:08:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;&lt;i&gt;[Note: all the information was gathered based on a close-to-Beta 1
build of .NET Framework 4.0 and Visual Studio 2010. Details may vary
and change]&lt;/i&gt;&lt;br&gt;&lt;br&gt;We already talked about some basics of discovery support in WCF4. Another nice feature in this area are announcements.&lt;br&gt;If you as a service consumer are interested when service endpoints go on- and offline you can get notified. The only thing to do is to host an AnnouncementService (provided by WCF4) on the consuming side and subscribe to the OnlineAnnouncementReceived and OfflineAnnouncementReceived events.&lt;br&gt;&lt;br&gt;For this work the service needs to send out announcements messages in the first place. This can be achieved by adding &lt;br&gt;an announcement endpoint:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;configuration&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;system.serviceModel&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;service name="HelloService"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; behaviorConfiguration="serviceBehavior"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint address=""&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; binding="basicHttpBinding"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; contract="IHelloService" /&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint name="udpDiscovery" kind="udpDiscoveryEndpoint"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/service&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;behaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceBehaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;behavior name="serviceBehavior"&amp;gt;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceDiscovery&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;announcementEndpoints&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint name="udpAnnouncement" kind="udpAnnouncementEndpoint"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/announcementEndpoints&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/serviceDiscovery&amp;gt;&lt;br&gt;&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/behavior&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/serviceBehaviors&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/behaviors&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;/system.serviceModel&amp;gt;&lt;br&gt;&amp;lt;/configuration&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;This is all that needs to be done on the service host side. Remember that the udpAnnouncementEndpoint is one of the &lt;a href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415330.aspx"&gt;new standard endpoints in WCF4&lt;/a&gt;.&lt;br&gt;&lt;br&gt;Consumers can then use the approach outlined in the introduction of this post. I.e. creating an AnnouncementService:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;var announcementService = new AnnouncementService();&lt;br&gt;announcementService.OnlineAnnouncementReceived +=&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;new EventHandler&amp;lt;AnnouncementEventArgs&amp;gt;(announcementService_OnlineAnnouncementReceived);&lt;br&gt;announcementService.OfflineAnnouncementReceived +=&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;new EventHandler&amp;lt;AnnouncementEventArgs&amp;gt;(announcementService_OfflineAnnouncementReceived);&lt;br&gt;&lt;br&gt;announcementServiceHost = new ServiceHost(announcementService);&lt;br&gt;announcementServiceHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());&lt;br&gt;announcementServiceHost.Open();&lt;br&gt;&lt;/font&gt;&lt;br&gt;In the registered event handlers we can then check whether this is actually an announcement for the contract we are interested in:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;private void announcementService_OnlineAnnouncementReceived(object sender, AnnouncementEventArgs e)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;var contractXQN = GetContractXmlQualifiedName();&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (e.AnnouncementMessage.EndpointDiscoveryMetadata.ContractTypeNames.Contains(contractXQN))&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;FireOnlineEvent();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;private void announcementService_OfflineAnnouncementReceived(object sender, AnnouncementEventArgs e)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;var contractXQN = GetContractXmlQualifiedName();&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (e.AnnouncementMessage.EndpointDiscoveryMetadata.ContractTypeNames.Contains(contractXQN))&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;FireOfflineEvent();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;private static XmlQualifiedName GetContractXmlQualifiedName()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;var contract = ContractDescription.GetContract(typeof(IHelloService));&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;var contractXQN = new XmlQualifiedName(contract.Name, contract.Namespace);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return contractXQN;&lt;br&gt;}&lt;br&gt;&lt;/font&gt;&lt;br&gt;If we now combine online/offline announcements with full &lt;a href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415329.aspx"&gt;metadata-driven discovery&lt;/a&gt; we can build sophisticated service-oriented peer solutions.&lt;br&gt;This is very powerful stuff!&lt;br&gt;&lt;br&gt;That's it for now for a first introduction to discovery announcements in WCF4.&lt;br&gt;Stay tuned for more.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415332" width="1" height="1"&gt;</content><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415332</wfw:commentRss></entry><entry><title>[What's new in WCF4] Standard endpoints - or: &amp;quot;Look ma: streamlined infrastructure and system endpoints!&amp;quot;</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415330.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415330</id><created>2009-05-08T09:31:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;&lt;i&gt;[Note: all the information was gathered based on a close-to-Beta 1
build of .NET Framework 4.0 and Visual Studio 2010. Details may vary
and change]&lt;/i&gt;&lt;br&gt;&lt;br&gt;As &lt;a href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415329.aspx"&gt;indicated in my post about discovery features&lt;/a&gt; there is a new feature in WCF4 called standard endpoints. The purpose of standard endpoints in WCF config is to allow for reusable pre-configured endpoints.&lt;br&gt;We all know that endpoints in WCF have many moving parts (address, binding, contract, behaviors). In some cases some of these parts are constrained. This is most common with infrastructure or system endpoints where the contract is fixed and provided externally to the service. Examples include MEX, discovery, WF instance control endpoints, etc.&lt;br&gt;&lt;br&gt;To specify a standard endpoint we configure a normal endpoint and then specify its "kind" attribute:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;system.serviceModel&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;service name="HelloService"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;endpoint kind="udpDiscoveryEndpoint" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/service&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;behaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;behavior&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;serviceDiscovery /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/behavior&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/behaviors&amp;gt;&lt;br&gt;&amp;lt;/system.serviceModel&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;These are the pre-defined standard endpoints (screenshot from Visual Studio's XML Schema explorer):&lt;br&gt;&lt;br&gt;&lt;img src="http://static.thinktecture.com/christianweyer/WCF4_Standard_EPs_1.png" alt="WCF4 standard endpoints"&gt;&lt;br&gt;&lt;br&gt;We can also optionally specify a reusable endpointConfiguration for the endpoint using the new standardEndpoints section in config. This is similar to how one would specify a bindingConfiguration for a binding:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;system.serviceModel&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;service name="HelloService"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;endpoint&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;kind="udpDiscoveryEndpoint"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;endpointConfiguration="udpDiscoveryEndpointSettings"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/service&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/services&amp;gt;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;standardEndpoints&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;udpDiscoveryEndpoint&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;standardEndpoint&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;name="udpDiscoveryEndpointSettings"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;multicastAddress="soap.udp://239.255.255.252:3704"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;maxResponseDelay="00:00:02"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;transportSettings&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;duplicateMessageHistoryLength="2048"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;maxPendingMessageCount="5"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;maxReceivedMessageSize="8192"&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;maxBufferPoolSize="262144"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/standardEndpoint&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/udpDiscoveryEndpoint&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/standardEndpoints&amp;gt;&lt;br&gt;&lt;/b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;behaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;behavior&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;serviceDiscovery /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/behavior&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/behaviors&amp;gt;&lt;br&gt;&amp;lt;/system.serviceModel&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;Not a very big but surely a convenient addition to WCF's feature set.&lt;br&gt;&amp;nbsp;&lt;br&gt;That's it for now for a first look into standard endpoints in WCF4.&lt;br&gt;Stay tuned for more.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415330" width="1" height="1"&gt;</content><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415330</wfw:commentRss></entry><entry><title>[What's new in WCF4] Dynamic service and endpoint discovery - or: &amp;quot;Look ma: I just need the contract to talk to my service!&amp;quot;</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415329.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415329</id><created>2009-05-08T09:22:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;&lt;i&gt;[Note: all the information was gathered based on a close-to-Beta 1
build of .NET Framework 4.0 and Visual Studio 2010. Details may vary
and change]&lt;br&gt;&lt;br&gt;&lt;/i&gt;"WCF is so easy, easy as ABC!" I am sure we all can still hear this marketing sentence echoing down the halls of building 42 on Redmond campus.&lt;br&gt;&lt;br&gt;For exposing WCF services we need endpoints and endpoints need A, B, and C - yeah, you know that.&lt;br&gt;For consuming WCF services we need the endpoint information from the service, the A(ddress), the B(inding), and the (C)ontract - yeah you know that.&lt;br&gt;&lt;br&gt;But wait...&lt;br&gt;What if the endpoints change frequently? What if the actual binding information is changed from time to time? We always need to make sure that all the consumers have the same exact updated endpoint configuration. Tedious, error-prone, often unnecessary.&lt;br&gt;&lt;br&gt;Hm, what if I have a closed environment where I could use something like dynamic discovery of available endpoints? Something like a UDP-based multicast message exchange which receives the endpoint information from an available service. Based on the discovery information (which is the endpoint address and some more information not that necessary for now) sent back by this service I as a consumer can then go ahead and talk to this service.&lt;br&gt;It turns out there is something called &lt;a href="http://specs.xmlsoap.org/ws/2005/04/discovery/ws-discovery.pdf"&gt;WS-Discovery&lt;/a&gt; and WCF in .NET Framework 4 supports this standard.&lt;br&gt;&lt;br&gt;The service discovery feature enables client applications to dynamically discover service addresses at runtime in an interoperable way using WS-Discovery. The WS-Discovery specification outlines the message exchange patterns required for performing light-weight discovery of services, both by multicast (ad hoc) and unicast (utilizing a dedicated network resource, often referred to as a proxy).&lt;br&gt;I will be talking about the ad-hoc approach in this post.&lt;br&gt;&lt;br&gt;How does it work?&lt;br&gt;The following is the config file for a sample Hello service. Nothing needs to be done or changed in code, so you can use your very own common WCF services from yesterday.&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;configuration&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;system.serviceModel&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;service name="HelloService"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; behaviorConfiguration="serviceBehavior"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;host&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;baseAddresses&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add baseAddress="http://localhost:7777/Services/Hello"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/baseAddresses&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/host&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;endpoint address=""&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; binding="basicHttpBinding"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; contract="IHelloService" /&amp;gt;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint name="udpDiscovery" kind="udpDiscoveryEndpoint"/&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/service&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;behaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceBehaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;behavior name="serviceBehavior"&amp;gt;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceDiscovery /&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/behavior&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/serviceBehaviors&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/behaviors&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/system.serviceModel&amp;gt;&lt;br&gt;&amp;lt;/configuration&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;With this basic configuration for a service host we enable service and endpoint discovery for our service. Here we use a new feature of WCF4 called standard endpoints (by specifiying the "kind" attribute on the udpDiscovery endpoint). Some more information on standard endpoints in a later post.&lt;br&gt;&lt;br&gt;If now a consumer wants to talk to a service which supports endpoints for IHelloService she can use the client-side discovery API like this:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;DiscoveryClient discoveryClient = new DiscoveryClient("udpDiscoveryEndpoint");&lt;br&gt;FindCriteria findCriteria = new FindCriteria(typeof(IHelloService));&lt;br&gt;FindResponse findResponse = discoveryClient.Find(findCriteria);&lt;br&gt;&lt;br&gt;if (findResponse.Endpoints.Count &amp;gt; 0)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;EndpointAddress address = findResponse.Endpoints[0].Address;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ChannelFactory&amp;lt;IHelloServiceChannel&amp;gt; factory = new ChannelFactory&amp;lt;IHelloServiceChannel&amp;gt;(&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;new BasicHttpBinding(), address);&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;IHelloServiceChannel client = new factory.CreateChannel();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;client.SayIt("Hello from WCF4!");&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;client.Close();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;factory.Close();&lt;br&gt;}&lt;br&gt;&lt;/font&gt;&lt;br&gt;Pretty easy, eh? We need the contract, the binding and get the actual endpoint address as a result from the discovery process. Cool!&lt;br&gt;&lt;br&gt;But wait...&lt;br&gt;I still need to know about the binding. I still need to kn ow that here we need a basicHttpBinding. But what if the binding changes? I mean not something dramatic like from a session-less to a session-bound binding (which most probably would also mean changing parts of at least the consuming code) - more something like moving from basicHttpBinding to a custom binding with binary-over-http.&lt;br&gt;&lt;br&gt;There is rescue. And this rescue has been in the WCF stack from the very first version on and is nothing new in WCF4. It is called MetadataResolver.&lt;br&gt;We can pass a MEX (MetadataExchange, based on &lt;a href="http://xml.coverpages.org/WS-MetadataExchange.pdf"&gt;WS-MetadataExchange&lt;/a&gt;) address to the static Resolve method. The MetadataResolver will then look for the service's MEX endpoint and retrieve metadata for a given contract (in our case this would be IHelloService).&lt;br&gt;First we need to add a MEX endpoint to our service:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;endpoint address="mex"&lt;br&gt;&amp;nbsp; binding="mexHttpBinding"&lt;br&gt;&amp;nbsp; contract="IMetadataExchange" /&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;Then the consumer can act like this:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;ServiceEndpointCollection endpoints = MetadataResolver.Resolve(typeof(IHelloService), mexAddress);&lt;/font&gt;&lt;br&gt;&lt;br&gt;We then have a collection of endpoints matching the contract criteria in our hands.&lt;br&gt;Now let's take one step further and combine the two ideas:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Expose the MEX endpoint of a service with discovery.&lt;/li&gt;&lt;li&gt;Let the consumer discover the MEX endpoint via DiscoveryClient (and just this one).&lt;/li&gt;&lt;li&gt;Let the consumer obtain endpoint information via the MEX endpoint by using the MetadataResolver.&lt;/li&gt;&lt;li&gt;Let the consumer call the service, with A,B, and C - but originally (read: at compile time) the consuming code only needs to know about the contract, the functional interface.&lt;/li&gt;&lt;/ul&gt;For convenience I wrapped this code into a custom ChannelFactory&amp;lt;TChannel&amp;gt; implementation which can be used in the described scenario.&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;public class SimpleDiscoveryChannelFactory&amp;lt;TChannel&amp;gt; : ChannelFactory&amp;lt;TChannel&amp;gt;&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;private bool initialized;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;protected override void ApplyConfiguration(string configurationName)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (!initialized)&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;base.ApplyConfiguration(configurationName);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var dc = new DiscoveryClient(new UdpDiscoveryEndpoint());&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var fc = FindCriteria.CreateMexEndpointCriteria();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;fc.MaxResults = 1;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var fr = dc.Find(fc);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (fr.Endpoints.Count &amp;gt; 0)&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var eps = MetadataResolver.Resolve(typeof(TChannel), fr.Endpoints[0].Address);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (eps.Count &amp;gt; 0)&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;initialized = true;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;this.InitializeEndpoint(eps[0]);&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;else throw new MetadataException("Could not find appropriate endpoint for contract.");&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;else throw new DiscoveryException("Could not find appropriate MEX endpoint.");&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/font&gt;&lt;i&gt;Note&lt;/i&gt;: it is not really recommended to do network calls before Open() is called, so this is just for illustration purposes here.&lt;br&gt;&lt;br&gt;I use ad-hoc discovery here through UDP and tell the client API to stop discovering when one matching MEX service endpoint was found based on the FindCriteria.&lt;br&gt;Then the consumer just has some few lines of actual code to call a service based on the contract at hand:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;var cf = new SimpleDiscoveryChannelFactory&amp;lt;IHelloServiceChannel&amp;gt;();&lt;br&gt;var client = cf.CreateChannel();&lt;br&gt;&lt;br&gt;Console.WriteLine(client.SayIt("Hello from WCF4!");&lt;br&gt;&lt;br&gt;client.Close();&lt;br&gt;cf.Close();&lt;br&gt;&lt;/font&gt;&lt;br&gt;Yes, it works :)&lt;br&gt;There you are: "Look ma: I just need the contract to talk to my service(s)!" We get the current binding and endpoint address dynamically.&lt;br&gt;&lt;br&gt;&lt;i&gt;Note:&lt;br&gt;We can only use on the consuming side what is actually exposed via metadata. As you all know the throttles and quotas on the bindings are not exposed via metadata.&lt;br&gt;&lt;/i&gt;&lt;br&gt;That's it for now for a first introduction to dynamic discovery in WCF4.&lt;br&gt;Stay tuned for more.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415329" width="1" height="1"&gt;</content><slash:comments>5</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415329</wfw:commentRss></entry><entry><title>Manually deploying .NET Services Service Bus-enabled applications</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415328.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415328</id><created>2009-05-08T07:04:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;If your application is using the Service Bus features from the .NET Services offerings in the Azure Services platform then you are most likely using config settings for certain relay bindings and the like.&lt;br&gt;When you want to deploy your application to other machines - especially to web sites hosted with an ISP - you need to make sure that all the config entries are valid and thus need to make sure that all binding and binding elements and behavior extensions as well as policy and WSDL importers are registered. This is usually done by running either the .NET Services SDK installer or the .NET Services Redist installer. Both will add the necessary config section entries to your machine.config file.&lt;br&gt;&lt;br&gt;But when hosting your web app you most probably just have access to the ISP's space via an FTP connection. No problem: just add the necessary registrations in your app.config or web.config. This is kind of a template for the current .NET Services build which you can add to your config file.&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt; &lt;br&gt;&amp;lt;configuration&amp;gt; &lt;br&gt;&amp;nbsp; &amp;lt;system.serviceModel&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extensions&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;lt;behaviorExtensions&amp;gt; &lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="connectionStatusBehavior" type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/behaviorExtensions&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;lt;bindingElementExtensions&amp;gt;&lt;/b&gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="tcpRelayTransport" type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="httpRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpRelayTransportElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="httpsRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="onewayRelayTransport" type="Microsoft.ServiceBus.Configuration.OnewayRelayTransportElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/bindingElementExtensions&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;lt;bindingExtensions&amp;gt;&lt;/b&gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="basicHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="basicHttpRelayContextBinding" type="Microsoft.ServiceBus.Configuration.BasicHttpRelayContextBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="webHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="wsHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WSHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="wsHttpRelayContextBinding" type="Microsoft.ServiceBus.Configuration.WSHttpRelayContextBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="ws2007HttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="ws2007FederationHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WS2007FederationHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="netTcpRelayBinding" type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="netTcpRelayContextBinding" type="Microsoft.ServiceBus.Configuration.NetTcpRelayContextBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="netOnewayRelayBinding" type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="netEventRelayBinding" type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/bindingExtensions&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/extensions&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;client&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;metadata&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;lt;policyImporters&amp;gt; &lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension type="Microsoft.ServiceBus.Description.TcpRelayTransportBindingElementImporter, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension type="Microsoft.ServiceBus.Description.HttpRelayTransportBindingElementImporter, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension type="Microsoft.ServiceBus.Description.OnewayRelayTransportBindingElementImporter, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/policyImporters&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;lt;wsdlImporters&amp;gt;&lt;/b&gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension type="Microsoft.ServiceBus.Description.StandardRelayBindingImporter, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension type="Microsoft.ServiceBus.Description.TcpRelayTransportBindingElementImporter, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension type="Microsoft.ServiceBus.Description.HttpRelayTransportBindingElementImporter, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension type="Microsoft.ServiceBus.Description.OnewayRelayTransportBindingElementImporter, Microsoft.ServiceBus, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/wsdlImporters&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/metadata&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/client&amp;gt; &lt;br&gt;&amp;nbsp; &amp;lt;/system.serviceModel&amp;gt; &lt;br&gt;&amp;lt;/configuration&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;The rest is easy then. Just add your service and client configuration as you need. Obviously the .NET Services DLLs (which can be found in the SDK) need to be in the web project’s bin folder and the project needs to reference them.&lt;br&gt;Done.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415328" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415328</wfw:commentRss></entry><entry><title>[What's new in WCF4] .svc-less Activation - or: &amp;quot;Look ma: my [REST] URLs look good!&amp;quot;</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/cweyer/archive/2009/05/08/415327.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415327</id><created>2009-05-08T06:37:00Z</created><content type="text/html" mode="escaped">&lt;br&gt;&lt;i&gt;[Note: all the information was gathered based on a close-to-Beta 1
build of .NET Framework 4.0 and Visual Studio 2010. Details may vary
and change]&lt;/i&gt;&lt;br&gt;&lt;br&gt;Another interesting and most wanted feature in WCF4 is .svc-less activation when WAS-hosting WCF services. This essentially means that I do no longer need to have a physical .svc file for each of my services but just can specify the activation path in config.&lt;br&gt;So, with this simple WAS-hosted WCF project (without any .svc file)...&lt;br&gt;&lt;br&gt;&lt;img src="http://static.thinktecture.com/christianweyer/WCF4_ServiceActivation_1.png" alt="WCF4 .svc-less activation"&gt;&lt;br&gt;...we can have this web.config section for WCF:&lt;br&gt;&lt;br&gt;&lt;font face="Courier New"&gt;&amp;lt;system.serviceModel&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceHostingEnvironment&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;serviceActivations&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add relativeAddress="/Hello.svc" service="HelloService"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add relativeAddress="/Hello" service="HelloService"/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/serviceActivations&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/serviceHostingEnvironment&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;services&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;service name="HelloService"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;endpoint binding="webHttpBinding" contract="IHelloService" /&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/service&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/services&amp;gt;&lt;br&gt;[...]&lt;br&gt;&lt;/font&gt;&lt;br&gt;This means that we now have one endpoint which can be activated (or 'addressed' in the first place) via two URIs, namely &lt;br&gt;&lt;ul&gt;&lt;li&gt;http://myserver/myapp/Hello.svc and &lt;/li&gt;&lt;li&gt;http://myserver/myapp/Hello&lt;/li&gt;&lt;/ul&gt;Of course you can just omit the entry for Hello.svc and then you can activate your WAS-hosted service via&lt;br&gt;&lt;ul&gt;&lt;li&gt;http://myserver/myapp/Hello.&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;Pure joy for the REST-afarians :)&lt;br&gt;(and yes: this also works with any other binding)&lt;br&gt;&lt;br&gt;That's it for now for a first introduction to .svc-less activation in WCF4.&lt;br&gt;Stay tuned for more.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415327" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/cweyer/commentrss.aspx?PostID=415327</wfw:commentRss></entry></feed>