<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Patrick Cauldwell's Blog</title>
    <link>http://www.cauldwell.net/patrick/blog/</link>
    <description>stuff I do at work, and occasionally some stuff I don't</description>
    <language>en-us</language>
    <copyright>Patrick Cauldwell</copyright>
    <lastBuildDate>Wed, 27 Oct 2010 21:32:51 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>patrick@cauldwell.net</managingEditor>
    <webMaster>patrick@cauldwell.net</webMaster>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PatrickCauldwellsBlog" /><feedburner:info uri="patrickcauldwellsblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>45.491024</geo:lat><geo:long>-122.957452</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=9b42e67a-97fb-468b-94ba-f5a6bfe8af28</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,9b42e67a-97fb-468b-94ba-f5a6bfe8af28.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,9b42e67a-97fb-468b-94ba-f5a6bfe8af28.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9b42e67a-97fb-468b-94ba-f5a6bfe8af28</wfw:commentRss>
      
      <title>Using MEF for extensible XML processing</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,9b42e67a-97fb-468b-94ba-f5a6bfe8af28.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/yH6gCiTBeS4/UsingMEFForExtensibleXMLProcessing.aspx</link>
      <pubDate>Wed, 27 Oct 2010 21:32:51 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
It’s not uncommon to want to dynamically add new sections to an XML file, such as&#xD;
a config file, without having to recompile existing code for processing said XML file. &#xD;
One common example is the way that .NET’s app.config file supports a config section&#xD;
/ config section handler model.  You can add new arbitrary XML that is specific&#xD;
to a particular bit of code in its schema, then register a “handler” for that config&#xD;
section so that the standard System.Configuration classes can read and deal with that&#xD;
otherwise unknown schema.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Rather then explicitly registering “handlers” in the XML file itself, we can use the&#xD;
Managed Extensibility Framework (MEF), which is now a fully baked part of the .NET&#xD;
4 framework.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Let’s say I start off with a configuration file that looks like this&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: xml;"&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;&#xD;
&amp;lt;configuration&amp;gt;&#xD;
  &amp;lt;products&amp;gt;&#xD;
    &amp;lt;product name="Product1"&amp;gt;&#xD;
      &amp;lt;P1Config&amp;gt;&#xD;
        &amp;lt;secretP1Value&amp;gt;42&amp;lt;/secretP1Value&amp;gt;&#xD;
      &amp;lt;/P1Config&amp;gt;&#xD;
    &amp;lt;/product&amp;gt;&#xD;
    &amp;lt;product name="Product2"&amp;gt;&#xD;
      &amp;lt;Product2Config&amp;gt;&#xD;
        &amp;lt;installedFeatures&amp;gt;&#xD;
          &amp;lt;feature id="1"/&amp;gt;&#xD;
          &amp;lt;feature id="36"/&amp;gt;&#xD;
        &amp;lt;/installedFeatures&amp;gt;&#xD;
      &amp;lt;/Product2Config&amp;gt;&#xD;
    &amp;lt;/product&amp;gt;&#xD;
  &amp;lt;/products&amp;gt;&#xD;
&amp;lt;/configuration&amp;gt;&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
I want to be able to add new &amp;lt;product&amp;gt; sections in the future which will contain&#xD;
XML that only that particular product’s plugin will know what to do with.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
MEF is all about the “plugin” pattern.  It allows me to declare “Exported” contracts&#xD;
that plugins essentially publish for use, and to declare that other components “Import”&#xD;
those plugins, meaning they require a runtime instance of one or more of those published&#xD;
exports.  For the sake of the above example, I’ve defined an interface that each&#xD;
product plugin will need to support to process the XML from its config section.&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp;"&gt;interface IProductPlugin&#xD;
{&#xD;
    bool Configure(XElement config);&#xD;
}&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
When the overall XML file is processed, an instance of each product’s plugin will&#xD;
be instantiated and “fed” the XElement that represents its config section.  MEF&#xD;
makes it easy to choose which plugin gets loaded for each section using named contracts. &#xD;
The following two plugins&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp;"&gt;[Export("Product1", typeof(IProductPlugin))]&#xD;
public class ProductOnePlugin : IProductPlugin&#xD;
{&#xD;
    public bool Configure(XElement config)&#xD;
    {&#xD;
        var secret = from el in config.Descendants()&#xD;
                     where el.Name == "secretP1Value"&#xD;
                     select el.Value;&#xD;
&#xD;
        Debug.WriteLine(secret.FirstOrDefault());&#xD;
&#xD;
        return true;&#xD;
    }&#xD;
}&#xD;
&#xD;
[Export("Product2", typeof(IProductPlugin))]&#xD;
public class ProductTwoPlugin : IProductPlugin&#xD;
{&#xD;
    public bool Configure(XElement config)&#xD;
    {&#xD;
        var installed = from el in config.Descendants()&#xD;
                        where el.Name == "feature"&#xD;
                        select el.Attribute("id").Value;&#xD;
&#xD;
        foreach (var off in installed)&#xD;
        {&#xD;
            Debug.WriteLine(off);&#xD;
        }&#xD;
&#xD;
        return true;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
both export the IProductPlugin interface, but they also declare a name under which&#xD;
it will be exported.  We can use a corresponding “name” attribute in the &amp;lt;product&amp;gt;&#xD;
element of each section to get the right plugin.  At runtime, the code to load&#xD;
the file reads each product element and instantiates the right plugin by asking MEF&#xD;
for the named instance from MEF’s catalog.&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp;"&gt;XDocument top = XDocument.Load(s);&#xD;
var products = from product in top.Root.Element("products").Elements()&#xD;
               select product;&#xD;
&#xD;
foreach (var prod in products)&#xD;
{&#xD;
    string name = prod.Attribute("name").Value;&#xD;
    var plugin = _container.GetExport&amp;lt;IProductPlugin&amp;gt;(name);&#xD;
    plugin.Value.Configure(prod);&#xD;
}&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
The key in this case is the GetExport method.  It optionally takes that arbitrary&#xD;
string and tries to find the right instance from the catalog.  In this particular&#xD;
case, for the sake of simplicity, the catalog is loaded from the running assembly.&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp;"&gt;_container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly()));&#xD;
_container.ComposeParts(this);&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
In practice, I would use the DirectoryCatalog class to build the catalog from all&#xD;
the assemblies in one directory, which would allow new plugin assemblies to be simply&#xD;
dropped into place without anything needing to be compiled.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=yH6gCiTBeS4:HuBLWcJlayA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=yH6gCiTBeS4:HuBLWcJlayA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=yH6gCiTBeS4:HuBLWcJlayA:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=yH6gCiTBeS4:HuBLWcJlayA:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=yH6gCiTBeS4:HuBLWcJlayA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=yH6gCiTBeS4:HuBLWcJlayA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=yH6gCiTBeS4:HuBLWcJlayA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=yH6gCiTBeS4:HuBLWcJlayA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=yH6gCiTBeS4:HuBLWcJlayA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,9b42e67a-97fb-468b-94ba-f5a6bfe8af28.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/UsingMEFForExtensibleXMLProcessing.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=c32e2886-5843-45a8-9051-3966b92a01fe</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,c32e2886-5843-45a8-9051-3966b92a01fe.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,c32e2886-5843-45a8-9051-3966b92a01fe.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=c32e2886-5843-45a8-9051-3966b92a01fe</wfw:commentRss>
      <slash:comments>1</slash:comments>
      
      <title>Intro to Windows Workflow 4</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,c32e2886-5843-45a8-9051-3966b92a01fe.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/r3lwoQG-bUk/IntroToWindowsWorkflow4.aspx</link>
      <pubDate>Wed, 27 Oct 2010 16:40:47 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
I’ll be &lt;a href="http://padnug.org/meetings.aspx?ID=225"&gt;speaking at PADNUG&lt;/a&gt; next&#xD;
Tuesday about the wonders of WF 4 and how to apply it to real world problems. &#xD;
We’ll look at what problems WF solves, when it might be appropriate, and how to get&#xD;
started building your own workflows.  We’ll also look at using WF/WCF integration&#xD;
to create “declarative services” or “workflow services” quickly and easily.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=r3lwoQG-bUk:QwzzCf7nLhc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=r3lwoQG-bUk:QwzzCf7nLhc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=r3lwoQG-bUk:QwzzCf7nLhc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=r3lwoQG-bUk:QwzzCf7nLhc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=r3lwoQG-bUk:QwzzCf7nLhc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=r3lwoQG-bUk:QwzzCf7nLhc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=r3lwoQG-bUk:QwzzCf7nLhc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=r3lwoQG-bUk:QwzzCf7nLhc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=r3lwoQG-bUk:QwzzCf7nLhc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,c32e2886-5843-45a8-9051-3966b92a01fe.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/IntroToWindowsWorkflow4.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=8e51fbca-77fe-45e8-8c03-d1967c494b5c</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,8e51fbca-77fe-45e8-8c03-d1967c494b5c.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,8e51fbca-77fe-45e8-8c03-d1967c494b5c.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8e51fbca-77fe-45e8-8c03-d1967c494b5c</wfw:commentRss>
      
      <title>Change of scene</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,8e51fbca-77fe-45e8-8c03-d1967c494b5c.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/AGKHEivSPdI/ChangeOfScene.aspx</link>
      <pubDate>Wed, 15 Sep 2010 18:30:54 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
As of this week, I’m now working at WebMD Health Service in NW Portland.  I’m&#xD;
looking forward to working with the very smart people here, and learning about the&#xD;
latest in ASP.NET and Agile development in the enterprise.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
More information to follow as the situation warrants. &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.cauldwell.net/patrick/blog/content/binary/WindowsLiveWriter/Changeofscene_A1BC/wlEmoticon-smile_2.png"&gt;&lt;/img&gt;&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=AGKHEivSPdI:be21t4LbEhQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=AGKHEivSPdI:be21t4LbEhQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=AGKHEivSPdI:be21t4LbEhQ:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=AGKHEivSPdI:be21t4LbEhQ:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=AGKHEivSPdI:be21t4LbEhQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=AGKHEivSPdI:be21t4LbEhQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=AGKHEivSPdI:be21t4LbEhQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=AGKHEivSPdI:be21t4LbEhQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=AGKHEivSPdI:be21t4LbEhQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,8e51fbca-77fe-45e8-8c03-d1967c494b5c.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/ChangeOfScene.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=a7121a47-fa7d-4271-afd0-d9e87f5095f1</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,a7121a47-fa7d-4271-afd0-d9e87f5095f1.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,a7121a47-fa7d-4271-afd0-d9e87f5095f1.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a7121a47-fa7d-4271-afd0-d9e87f5095f1</wfw:commentRss>
      <slash:comments>1</slash:comments>
      
      <title>Default button semantics in Silverlight, once more</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,a7121a47-fa7d-4271-afd0-d9e87f5095f1.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/lKHFZff4d1k/DefaultButtonSemanticsInSilverlightOnceMore.aspx</link>
      <pubDate>Thu, 02 Sep 2010 17:00:05 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;A while back I posted a &lt;a href="http://www.cauldwell.net/patrick/blog/DefaultButtonSemanticsInSilverlightRevisited.aspx"&gt;revision &lt;/a&gt;to&#xD;
my original default button sample that made it a bit easier to use, but there was&#xD;
still an issue...  If you invoke the button while the focus is still in a text&#xD;
box, any changes made to the text in the text box may not get pushed into the databinding&#xD;
source, since by default that happens when the text box loses focus.  I didn't&#xD;
come up with a good solution, but luckily somebody did. :)  I got the following&#xD;
revision from Glenn Orr, and this should solve the problem.  If you have any&#xD;
custom data entry controls, etc. you may have to add additional clauses to handle&#xD;
them, but this will work with text boxes for sure.&lt;br&gt;&lt;br&gt;&#xD;
Change the OnKeyUp method to look like this...&lt;br&gt;&lt;pre&gt;&lt;span style="font-family: Consolas; color: blue;"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br&gt;&lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;private void OnKeyUp(object sender, KeyEventArgs arg)&#xD;
{&#xD;
	  if (arg.Key == Key.Enter)&#xD;
			  if (peer != null)&#xD;
			   {&#xD;
					   if (sender is TextBox)&#xD;
					  {&#xD;
							   BindingExpression expression = (sender as TextBox).GetBindingExpression(TextBox.TextProperty);&#xD;
							   expression.UpdateSource();&#xD;
					  }&#xD;
					  ((IInvokeProvider)peer).Invoke();&#xD;
			  }&#xD;
}&lt;/pre&gt;&#xD;
This will make sure that any changes get pushed into the databinding source before&#xD;
the button is invoked. Thanks Glenn!&lt;br&gt;&lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=lKHFZff4d1k:SqqCf1iJuW4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=lKHFZff4d1k:SqqCf1iJuW4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=lKHFZff4d1k:SqqCf1iJuW4:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=lKHFZff4d1k:SqqCf1iJuW4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=lKHFZff4d1k:SqqCf1iJuW4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=lKHFZff4d1k:SqqCf1iJuW4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=lKHFZff4d1k:SqqCf1iJuW4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=lKHFZff4d1k:SqqCf1iJuW4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=lKHFZff4d1k:SqqCf1iJuW4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,a7121a47-fa7d-4271-afd0-d9e87f5095f1.aspx</comments>
      <category>Silverlight</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/DefaultButtonSemanticsInSilverlightOnceMore.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=0817f628-d359-4430-815e-48e9ed69ce26</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,0817f628-d359-4430-815e-48e9ed69ce26.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,0817f628-d359-4430-815e-48e9ed69ce26.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0817f628-d359-4430-815e-48e9ed69ce26</wfw:commentRss>
      
      <title>Code Camp sample app</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,0817f628-d359-4430-815e-48e9ed69ce26.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/PS7IFjMcV7Q/CodeCampSampleApp.aspx</link>
      <pubDate>Mon, 24 May 2010 03:26:25 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
The sample app I used for my Code Camp presentation is &lt;a href="http://www.cauldwell.net/patrick/files/codecamp.zip"&gt;here&lt;/a&gt;. &#xD;
I’ll post details about the sample later in the week.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PS7IFjMcV7Q:UmqBa8MXNaU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PS7IFjMcV7Q:UmqBa8MXNaU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PS7IFjMcV7Q:UmqBa8MXNaU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PS7IFjMcV7Q:UmqBa8MXNaU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PS7IFjMcV7Q:UmqBa8MXNaU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=PS7IFjMcV7Q:UmqBa8MXNaU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PS7IFjMcV7Q:UmqBa8MXNaU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=PS7IFjMcV7Q:UmqBa8MXNaU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PS7IFjMcV7Q:UmqBa8MXNaU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,0817f628-d359-4430-815e-48e9ed69ce26.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/CodeCampSampleApp.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=50a99489-e5e6-481c-879b-784fd7b9ddfc</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,50a99489-e5e6-481c-879b-784fd7b9ddfc.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,50a99489-e5e6-481c-879b-784fd7b9ddfc.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=50a99489-e5e6-481c-879b-784fd7b9ddfc</wfw:commentRss>
      
      <title>WPF 4: breaking change between RC and Release</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,50a99489-e5e6-481c-879b-784fd7b9ddfc.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/WkrVGco1TKw/WPF4BreakingChangeBetweenRCAndRelease.aspx</link>
      <pubDate>Thu, 15 Apr 2010 20:02:03 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
While I guess I understand why this would be a problem, I don’t understand why it&#xD;
worked before…&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If I want to create a style for a button, let’s say with a red background, I might&#xD;
create a brush resource that defines my special color of red, then reference that&#xD;
brush in a style resource like so&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: xml;"&gt;&amp;lt;SolidColorBrush x:Key="TheBrush"&amp;gt;&#xD;
    &amp;lt;SolidColorBrush.Color&amp;gt;Red&amp;lt;/SolidColorBrush.Color&amp;gt;&#xD;
&amp;lt;/SolidColorBrush&amp;gt;            &#xD;
&amp;lt;Style x:Key="RedButton" TargetType="Button"&amp;gt;&#xD;
    &amp;lt;Setter Property="Background" Value="{StaticResource TheBrush}"/&amp;gt;&#xD;
&amp;lt;/Style&amp;gt;&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
That works just fine.  I get a red button like this&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.cauldwell.net/patrick/blog/images/WPF4breakingchangebetweenRCandRelease_B305/image.png"&gt;&#xD;
            &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.cauldwell.net/patrick/blog/images/WPF4breakingchangebetweenRCandRelease_B305/image_thumb.png" width="90" height="42"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If the two resources are in the opposite order&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: xml;"&gt;&amp;lt;Style x:Key="RedButton" TargetType="Button"&amp;gt;&#xD;
    &amp;lt;Setter Property="Background" Value="{StaticResource TheBrush}"/&amp;gt;&#xD;
&amp;lt;/Style&amp;gt;&#xD;
&amp;lt;SolidColorBrush x:Key="TheBrush"&amp;gt;&#xD;
    &amp;lt;SolidColorBrush.Color&amp;gt;Red&amp;lt;/SolidColorBrush.Color&amp;gt;&#xD;
&amp;lt;/SolidColorBrush&amp;gt; &lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
then at runtime I’m going to end up with an exception because the resource “TheBrush”&#xD;
can’t be found.  Hmmm.  I suppose that makes sense if we imagine the XAML&#xD;
processor instancing objects as it comes to them in the XZML file.  It would&#xD;
try to instance “RedButton” and not be able to create the static reference to “TheBrush”&#xD;
because that object hasn’t been instanced yet.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If I happen to apply that style some something in my XAML &#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: xml; highlight: [2];"&gt;&amp;lt;Button &#xD;
    Style="{StaticResource RedButton}" &#xD;
    Content="Red Button" Height="23"&#xD;
    Click="button1_Click" /&amp;gt;&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
I’ll get a compile error.  OK.  If, however, the reference to “RedButton”&#xD;
is in something like a DataTemplate that doesn’t get applied until runtime, then I&#xD;
get a rather jarring runtime exception instead.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Again, I suppose this behavior makes sense given my theoretical model of the XAML&#xD;
processor (though it smacks of C++-ishness).  What doesn’t make sense is why&#xD;
it worked just fine in the RC, and just recompiling in the release of VS 2010 I now&#xD;
get runtime exceptions.  Something obviously changed in the way resources are&#xD;
loaded and/or referenced at runtime.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=WkrVGco1TKw:OwoWONFZd-o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=WkrVGco1TKw:OwoWONFZd-o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=WkrVGco1TKw:OwoWONFZd-o:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=WkrVGco1TKw:OwoWONFZd-o:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=WkrVGco1TKw:OwoWONFZd-o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=WkrVGco1TKw:OwoWONFZd-o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=WkrVGco1TKw:OwoWONFZd-o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=WkrVGco1TKw:OwoWONFZd-o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=WkrVGco1TKw:OwoWONFZd-o:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,50a99489-e5e6-481c-879b-784fd7b9ddfc.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/WPF4BreakingChangeBetweenRCAndRelease.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=0106405c-8a3a-4b4b-9400-ecd078e6d6ec</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,0106405c-8a3a-4b4b-9400-ecd078e6d6ec.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,0106405c-8a3a-4b4b-9400-ecd078e6d6ec.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0106405c-8a3a-4b4b-9400-ecd078e6d6ec</wfw:commentRss>
      
      <title>Workflow 4 Activity instances may be reused</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,0106405c-8a3a-4b4b-9400-ecd078e6d6ec.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/JAvc-Z1v4WI/Workflow4ActivityInstancesMayBeReused.aspx</link>
      <pubDate>Fri, 12 Feb 2010 19:14:40 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
We just caught this one this morning…  It looks like WF 4 reuses activity instances&#xD;
across workflow instances.  So if I have a WorkflowService that’s hosted in IIS,&#xD;
and I call it from two different client threads at the same time, the two workflow&#xD;
instances now running on the server may be using the same activity instances for child&#xD;
activities.  The documentation is not clear on this point, but that’s the behavior&#xD;
we observed.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The implication is that you have to treat calls to your Activity’s Execute method&#xD;
as stateless, and not maintain any state in your activity between calls to Execute. &#xD;
(Our specific problem was around EntityFramework containers.  Apparently they&#xD;
don’t like being called on multiple threads. :) )&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Makes sense, but it’s not clear at all from the documentation that it would be the&#xD;
case.  You can rely on the thread safety of your InArguments and OutArguments,&#xD;
since they are accessed through the context, but private fields are right out unless&#xD;
whatever you store in them is also threadsafe.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=JAvc-Z1v4WI:s4A4iPbFGTU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=JAvc-Z1v4WI:s4A4iPbFGTU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=JAvc-Z1v4WI:s4A4iPbFGTU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=JAvc-Z1v4WI:s4A4iPbFGTU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=JAvc-Z1v4WI:s4A4iPbFGTU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=JAvc-Z1v4WI:s4A4iPbFGTU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=JAvc-Z1v4WI:s4A4iPbFGTU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=JAvc-Z1v4WI:s4A4iPbFGTU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=JAvc-Z1v4WI:s4A4iPbFGTU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,0106405c-8a3a-4b4b-9400-ecd078e6d6ec.aspx</comments>
      <category>.NET 4</category>
      <category>Web Services</category>
      <category>WF</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/Workflow4ActivityInstancesMayBeReused.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=484a23ed-2508-4ba2-baa0-5a2efa13d325</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,484a23ed-2508-4ba2-baa0-5a2efa13d325.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,484a23ed-2508-4ba2-baa0-5a2efa13d325.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=484a23ed-2508-4ba2-baa0-5a2efa13d325</wfw:commentRss>
      
      <title>Unity and WorkflowServices hosted in IIS</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,484a23ed-2508-4ba2-baa0-5a2efa13d325.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/PBT-7P9HFdM/UnityAndWorkflowServicesHostedInIIS.aspx</link>
      <pubDate>Thu, 11 Feb 2010 01:03:13 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
This is probably one of those things that is obvious to everyone but me, but just&#xD;
in case it’s not… &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
We’re using Unity as our IoC container, and we are also using .NET 4 Workflow Services&#xD;
hosted in IIS, meaning .xamlx files that are served up by IIS 7.  In order to&#xD;
get full value out of Unity, we need one instance of the Unity container that gets&#xD;
properly configured somewhere that is then available to any WF activity that might&#xD;
need to resolve a reference.  But…since IIS is hosting, there’s no direct access&#xD;
to the WorkflowServiceHost to add the Unity container as an extension (which is how&#xD;
we do it in places where we are hosting using WorkflowApplication in WPF apps, etc.). &#xD;
I suspected that the solution was a WCF Service Behavior extension, because that’s&#xD;
how you set up a tracking participant if you are hosted in IIS, and luckily that turned&#xD;
out to be the case.  I’d been putting off nailing it down because I suspected&#xD;
it was hard, but as luck would have it (or, rather, the cleverness of the ServiceModel&#xD;
team) it’s not hard at all.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
First, we need a behavior extension that creates (and ultimately configures) the Unity&#xD;
container.  It has to implement IServiceBehavior, since we need it to be a service&#xD;
behavior to get access to the host.&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp;"&gt;public class UnityServiceBehavior : IServiceBehavior&#xD;
{&#xD;
&#xD;
    #region IServiceBehavior Members&#xD;
&#xD;
    public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection&amp;lt;ServiceEndpoint&amp;gt; endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)&#xD;
    {&#xD;
        &#xD;
    }&#xD;
&#xD;
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)&#xD;
    {&#xD;
         WorkflowServiceHost host = serviceHostBase as WorkflowServiceHost;&#xD;
         if (host != null)&#xD;
         {&#xD;
             IUnityContainer container = new UnityContainer();&#xD;
             host.WorkflowExtensions.Add&amp;lt;IUnityContainer&amp;gt;(delegate { return container; });&#xD;
         }&#xD;
   &#xD;
    }&#xD;
&#xD;
    public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)&#xD;
    {&#xD;
        &#xD;
    }&#xD;
&#xD;
    #endregion&#xD;
}&lt;/pre&gt;&#xD;
Secondly, we want it to be configurable through web.config, which calls for a BehaviorExtensionElement.  &lt;pre class="brush: csharp;"&gt;public class UnityBehaviorElementExtension : BehaviorExtensionElement&#xD;
{&#xD;
    public override Type BehaviorType&#xD;
    {&#xD;
        get { return typeof(UnityServiceBehavior); }&#xD;
    }&#xD;
&#xD;
    protected override object CreateBehavior()&#xD;
    {&#xD;
        return new UnityServiceBehavior();&#xD;
    }&#xD;
}&lt;/pre&gt;&lt;p&gt;&#xD;
Then, in our web.config, just register the extension, which in turn will configure&#xD;
and return behavior.&#xD;
&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;system.serviceModel&amp;gt;&#xD;
  &amp;lt;behaviors&amp;gt;&#xD;
    &amp;lt;serviceBehaviors&amp;gt;&#xD;
      &amp;lt;behavior&amp;gt;&#xD;
        &amp;lt;!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --&amp;gt;&#xD;
        &amp;lt;serviceMetadata httpGetEnabled="true"/&amp;gt;&#xD;
        &amp;lt;!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information --&amp;gt;&#xD;
        &amp;lt;serviceDebug includeExceptionDetailInFaults="false"/&amp;gt;&#xD;
        &amp;lt;unityExtension/&amp;gt;&#xD;
      &amp;lt;/behavior&amp;gt;&#xD;
    &amp;lt;/serviceBehaviors&amp;gt;&#xD;
  &amp;lt;/behaviors&amp;gt;&#xD;
  &amp;lt;extensions&amp;gt;&#xD;
    &amp;lt;behaviorExtensions&amp;gt;&#xD;
      &amp;lt;add name="unityExtension" type="UnityBehavior.UnityBehaviorElementExtension, UnityBehavior, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/&amp;gt;&#xD;
    &amp;lt;/behaviorExtensions&amp;gt;&#xD;
  &amp;lt;/extensions&amp;gt;&#xD;
  &amp;lt;serviceHostingEnvironment multipleSiteBindingsEnabled="true" /&amp;gt;&#xD;
&amp;lt;/system.serviceModel&amp;gt;&lt;/pre&gt;&lt;p&gt;&#xD;
In this case, the fact that the behavior element doesn’t include a name means the&#xD;
set of behaviors it contains will be applied to any WCF service that is relying on&#xD;
the default configuration (one of the coolest things in .NET 4!) which is how our&#xD;
.xamlx file works in this example.&#xD;
&lt;/p&gt;&lt;p&gt;&#xD;
Once all that’s done, from any activity in my .xamlx workflow I can access the IUnityContainer&#xD;
interface as an extension.&#xD;
&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;public sealed class CheckForUnity : CodeActivity&#xD;
{&#xD;
    // Define an activity input argument of type string&#xD;
    public OutArgument&amp;lt;bool&amp;gt; HasUnity { get; set; }&#xD;
&#xD;
    // If your activity returns a value, derive from CodeActivity&amp;lt;TResult&amp;gt;&#xD;
    // and return the value from the Execute method.&#xD;
    protected override void Execute(CodeActivityContext context)&#xD;
    {&#xD;
        IUnityContainer container = context.GetExtension&amp;lt;IUnityContainer&amp;gt;();&#xD;
&#xD;
        context.SetValue&amp;lt;bool&amp;gt;(HasUnity, (container != null));&#xD;
    }&#xD;
}&lt;/pre&gt;&lt;br&gt;&lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PBT-7P9HFdM:shJLUCKANV0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PBT-7P9HFdM:shJLUCKANV0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PBT-7P9HFdM:shJLUCKANV0:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PBT-7P9HFdM:shJLUCKANV0:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PBT-7P9HFdM:shJLUCKANV0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=PBT-7P9HFdM:shJLUCKANV0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PBT-7P9HFdM:shJLUCKANV0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=PBT-7P9HFdM:shJLUCKANV0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=PBT-7P9HFdM:shJLUCKANV0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,484a23ed-2508-4ba2-baa0-5a2efa13d325.aspx</comments>
      <category>.NET 4</category>
      <category>Unity</category>
      <category>WF</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/UnityAndWorkflowServicesHostedInIIS.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=a8f3e360-995b-4a81-821e-3ebcf9f72272</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,a8f3e360-995b-4a81-821e-3ebcf9f72272.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,a8f3e360-995b-4a81-821e-3ebcf9f72272.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a8f3e360-995b-4a81-821e-3ebcf9f72272</wfw:commentRss>
      <slash:comments>1</slash:comments>
      
      <title>Feedburner URL changes causing problems, working on it&amp;hellip;</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,a8f3e360-995b-4a81-821e-3ebcf9f72272.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/jvHIS7aMk9o/FeedburnerURLChangesCausingProblemsWorkingOnIthellip.aspx</link>
      <pubDate>Wed, 16 Dec 2009 17:51:04 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Feedburner has apparently started decorating the URLs they embed to link back to my&#xD;
full posts, which is causing my decrepit version of dasBlog to yak up 404’s. &#xD;
I’m working on it now, and apologize for the inconvenience.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jvHIS7aMk9o:cgmjcx6S70o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jvHIS7aMk9o:cgmjcx6S70o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jvHIS7aMk9o:cgmjcx6S70o:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jvHIS7aMk9o:cgmjcx6S70o:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jvHIS7aMk9o:cgmjcx6S70o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=jvHIS7aMk9o:cgmjcx6S70o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jvHIS7aMk9o:cgmjcx6S70o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=jvHIS7aMk9o:cgmjcx6S70o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jvHIS7aMk9o:cgmjcx6S70o:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,a8f3e360-995b-4a81-821e-3ebcf9f72272.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/FeedburnerURLChangesCausingProblemsWorkingOnIthellip.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=2666beef-4547-4503-8801-e63729cab54b</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,2666beef-4547-4503-8801-e63729cab54b.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,2666beef-4547-4503-8801-e63729cab54b.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2666beef-4547-4503-8801-e63729cab54b</wfw:commentRss>
      
      <title>WIF + VS 2010 + Win 7</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,2666beef-4547-4503-8801-e63729cab54b.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/QKCSygVpl60/WIFVS2010Win7.aspx</link>
      <pubDate>Wed, 16 Dec 2009 00:16:05 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Just in case someone is googling (binging?) this later…&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If you are running Visual Studio 2010 (Beta 2) on Windows 7, and you want to create&#xD;
a Windows Identity Foundation STS or relying party application, you need to run VS&#xD;
as an administrator, or it won’t create the project correctly.  I suspect it’s&#xD;
because it’s trying to install a cert, but there is some other stuff that fails too,&#xD;
probably as a result.  Once I ran VS as an admin, it all works fine.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
And, just for the record, WIF is awesome!  I’ve build an STS and relying app&#xD;
by hand for WCF 3, and this is SOOOOO much easier.  Excellent work guys!&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=QKCSygVpl60:8K8A0TcNiac:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=QKCSygVpl60:8K8A0TcNiac:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=QKCSygVpl60:8K8A0TcNiac:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=QKCSygVpl60:8K8A0TcNiac:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=QKCSygVpl60:8K8A0TcNiac:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=QKCSygVpl60:8K8A0TcNiac:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=QKCSygVpl60:8K8A0TcNiac:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=QKCSygVpl60:8K8A0TcNiac:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=QKCSygVpl60:8K8A0TcNiac:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,2666beef-4547-4503-8801-e63729cab54b.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/WIFVS2010Win7.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=5881acf2-819f-48e0-8090-620af4852550</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,5881acf2-819f-48e0-8090-620af4852550.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,5881acf2-819f-48e0-8090-620af4852550.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=5881acf2-819f-48e0-8090-620af4852550</wfw:commentRss>
      
      <title>Encrypting workflow instance data</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,5881acf2-819f-48e0-8090-620af4852550.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/1iSqrMqhKsQ/EncryptingWorkflowInstanceData.aspx</link>
      <pubDate>Wed, 25 Nov 2009 21:30:39 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
I’m trying to get a handle on WF 4 (which is awesome, BTW) and currently working on&#xD;
persistence.  We have a need to encrypt the workflow instance data, and it took&#xD;
me quite some time to figure out how that might best be done.  The biggest drawback&#xD;
to working with WF 4 right now is that the documentation is pretty lame.  There&#xD;
are very few samples, and beta 2 hasn’t been around long enough to generate the “this&#xD;
is how you solve that problem” blog posts we’ve all come to depend upon.  I looked&#xD;
at PersistenceParticipant, but couldn’t see a good way to make that do what I wanted,&#xD;
then a bunch more time trying to figure out what was going on in the SqlWorkflowInstanceStore,&#xD;
etc.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I think I’ve got a workable solution, although I’ve yet to actually try it out. &#xD;
Turns out that the SqlWorkflowInstanceStore keeps all that good data in varbinary(MAX)&#xD;
columns, and only messes with them via a set of stored procs that get created when&#xD;
you create the instance store schema.  It should be an easy thing to modify said&#xD;
stored procs to use native SQL 2005/2008 column level encryption, without having to&#xD;
change the schema at all.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I’ll let you know if it works…&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1iSqrMqhKsQ:XOIwTa_u1eE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1iSqrMqhKsQ:XOIwTa_u1eE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1iSqrMqhKsQ:XOIwTa_u1eE:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1iSqrMqhKsQ:XOIwTa_u1eE:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1iSqrMqhKsQ:XOIwTa_u1eE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=1iSqrMqhKsQ:XOIwTa_u1eE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1iSqrMqhKsQ:XOIwTa_u1eE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=1iSqrMqhKsQ:XOIwTa_u1eE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1iSqrMqhKsQ:XOIwTa_u1eE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,5881acf2-819f-48e0-8090-620af4852550.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/EncryptingWorkflowInstanceData.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=4a467c1a-e678-406f-836e-fc31283dc521</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,4a467c1a-e678-406f-836e-fc31283dc521.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,4a467c1a-e678-406f-836e-fc31283dc521.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=4a467c1a-e678-406f-836e-fc31283dc521</wfw:commentRss>
      
      <title>Can't reference System.ServiceModel.Web from WCF Library project</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,4a467c1a-e678-406f-836e-fc31283dc521.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/W15R7RRNMLE/CantReferenceSystemServiceModelWebFromWCFLibraryProject.aspx</link>
      <pubDate>Wed, 25 Nov 2009 21:23:57 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
This one stumped me for a bit today, so I wanted to get it out there for the search&#xD;
engines to find... I created a new WCF Service Library project in VS 2010, taking&#xD;
all the defaults and targeting .NET 4.0. I needed to add a [WebGet] attribute so that&#xD;
I could make REST calls to the service. To do that, you need a reference to System.ServiceModel.Web.dll.&#xD;
It didn't show up on the list of .NET references in the Add Reference... dialog. OK,&#xD;
weird. So then I tracked down the file manually and added it. It got added to the&#xD;
list of references, but showed up with the yellow-triangle "I don't know how&#xD;
to find this reference" icon. Huh. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The problem turned out to be that for some reason, the project got created with a&#xD;
target framework of .NET 4.0 Client Profile, which doesn't include that assembly.&#xD;
Once I switched to the full .NET 4.0 target, it works just fine. The Client Profile&#xD;
seems like a strange choice for a WCF Service Library.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=W15R7RRNMLE:mbMLIpmHXkc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=W15R7RRNMLE:mbMLIpmHXkc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=W15R7RRNMLE:mbMLIpmHXkc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=W15R7RRNMLE:mbMLIpmHXkc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=W15R7RRNMLE:mbMLIpmHXkc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=W15R7RRNMLE:mbMLIpmHXkc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=W15R7RRNMLE:mbMLIpmHXkc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=W15R7RRNMLE:mbMLIpmHXkc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=W15R7RRNMLE:mbMLIpmHXkc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,4a467c1a-e678-406f-836e-fc31283dc521.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/CantReferenceSystemServiceModelWebFromWCFLibraryProject.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=40ce04f0-9468-4ec8-b89d-652586aad76c</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,40ce04f0-9468-4ec8-b89d-652586aad76c.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,40ce04f0-9468-4ec8-b89d-652586aad76c.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=40ce04f0-9468-4ec8-b89d-652586aad76c</wfw:commentRss>
      
      <title>WPF/WF 4 challenge of the day</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,40ce04f0-9468-4ec8-b89d-652586aad76c.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/-IGmZm0plyc/WPFWF4ChallengeOfTheDay.aspx</link>
      <pubDate>Mon, 09 Nov 2009 17:09:28 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
So I’m trying to figure out how to use WF 4 as a controller for a Prism app, and already&#xD;
I’m running into some interesting behavior.  First off, in anything but a very&#xD;
simple solution, custom activities don’t show up in the toolbox like they should. &#xD;
That’s not a huge deal, but annoying. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Of greater interest (concern?) is the fact that if I put my workflow XAML file in&#xD;
the main WPF app solution, everything builds and runs just fine, except the workflow&#xD;
does absolutely nothing.  It just finished successfully, having run none of it’s&#xD;
activities.  If I take exactly the same XAML file and put it in another assembly,&#xD;
then run it from the WPF app, it works just like it should.  I’m guessing this&#xD;
is a byproduct of the new unified XAML engine, but I haven’t had time (or inclination&#xD;
really) to delve.  Mostly it just means I have to have at least one superfluous&#xD;
assembly, which for now isn’t too high a price to pay.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The day I installed beta 2, I managed to crash the workflow designer about 10 times,&#xD;
but it seems to have settled down now.  Overall, I really appreciate the new&#xD;
model for WF, which seems much more composable and easy to use.  &#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=-IGmZm0plyc:s3BVcC2V5Fg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=-IGmZm0plyc:s3BVcC2V5Fg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=-IGmZm0plyc:s3BVcC2V5Fg:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=-IGmZm0plyc:s3BVcC2V5Fg:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=-IGmZm0plyc:s3BVcC2V5Fg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=-IGmZm0plyc:s3BVcC2V5Fg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=-IGmZm0plyc:s3BVcC2V5Fg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=-IGmZm0plyc:s3BVcC2V5Fg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=-IGmZm0plyc:s3BVcC2V5Fg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,40ce04f0-9468-4ec8-b89d-652586aad76c.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/WPFWF4ChallengeOfTheDay.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=6a5d42ea-032c-42d9-9e24-461245469fd1</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,6a5d42ea-032c-42d9-9e24-461245469fd1.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,6a5d42ea-032c-42d9-9e24-461245469fd1.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=6a5d42ea-032c-42d9-9e24-461245469fd1</wfw:commentRss>
      
      <title>The new gig</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,6a5d42ea-032c-42d9-9e24-461245469fd1.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/ToUGvbMDFoE/TheNewGig.aspx</link>
      <pubDate>Fri, 06 Nov 2009 17:32:28 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
I realize this is a bit late, but as of just about 4 weeks ago I’m now the Architect&#xD;
at &lt;a href="http://www.eidpassport.com"&gt;Eid Passport&lt;/a&gt;.  I’m really looking&#xD;
forward to building some cool stuff, with a team that’s had quite a bit of experience&#xD;
in this space.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
In short, Eid Passport makes perimeter security systems for secure facilities, and&#xD;
manages access to those facilities by vendors.  For example, say you are the&#xD;
Coke delivery guy at a military base.  It’s a hassle to get through the gate&#xD;
every time you deliver, since they have to make sure it’s OK for you to be on the&#xD;
base.  Now the Coke guy has the option of going to our kiosk at the base and&#xD;
signing up for an access card that will allow him to spend much less time getting&#xD;
in and out.  We do some background checks, employment verification (does he still&#xD;
really work for Coke, etc.) and then issue a credential that he can use to get through&#xD;
the gate.  Now Coke delivery guy can make &lt;em&gt;N&lt;/em&gt; more deliveries in a day&#xD;
because he’s not spending time at the gate.  This is a new domain for me, so&#xD;
there’s a lot to learn, but it’s pretty exciting stuff.  All the way from a handheld&#xD;
scanner that reads all kinds of cards to back end access control and data processing&#xD;
servers.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If any of that sounds interesting to you, we’re looking for some additional developers. &#xD;
There are instructions on the website (see above) for how to submit your resume if&#xD;
you are interested.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=ToUGvbMDFoE:JtDPyLtGv6Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=ToUGvbMDFoE:JtDPyLtGv6Q:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=ToUGvbMDFoE:JtDPyLtGv6Q:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=ToUGvbMDFoE:JtDPyLtGv6Q:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=ToUGvbMDFoE:JtDPyLtGv6Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=ToUGvbMDFoE:JtDPyLtGv6Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=ToUGvbMDFoE:JtDPyLtGv6Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=ToUGvbMDFoE:JtDPyLtGv6Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=ToUGvbMDFoE:JtDPyLtGv6Q:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,6a5d42ea-032c-42d9-9e24-461245469fd1.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/TheNewGig.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=0aa76e13-9130-4044-b16c-ecf2fc46e58f</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,0aa76e13-9130-4044-b16c-ecf2fc46e58f.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,0aa76e13-9130-4044-b16c-ecf2fc46e58f.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0aa76e13-9130-4044-b16c-ecf2fc46e58f</wfw:commentRss>
      
      <title>New classes in the lineup</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,0aa76e13-9130-4044-b16c-ecf2fc46e58f.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/i7gjZhkVlhc/NewClassesInTheLineup.aspx</link>
      <pubDate>Wed, 17 Jun 2009 17:19:27 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
We’ve added some new classes to the &lt;a href="http://www.sftsrc.com"&gt;SoftSource&lt;/a&gt; training &lt;a href="http://events.sftsrc.com"&gt;calendar&lt;/a&gt;,&#xD;
including a one-day &lt;a href="http://events.sftsrc.com/EventDescription.aspx?EventId=1076&amp;amp;AbstractId=687"&gt;Blend&#xD;
2&lt;/a&gt; class, and &lt;a href="http://events.sftsrc.com/EventDescription.aspx?EventId=1061&amp;amp;AbstractId=682"&gt;SQL&#xD;
2008 for Developers&lt;/a&gt;.  Other offerings coming up are “Agile in a Day”, WPF,&#xD;
WCF, ASP.NET 3.5, LINQ, Silverlight, and of course, C#.  Discounts available&#xD;
for multiple students from the same organization, and custom on-site training also.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=i7gjZhkVlhc:TCbKfvQ6Ek4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=i7gjZhkVlhc:TCbKfvQ6Ek4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=i7gjZhkVlhc:TCbKfvQ6Ek4:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=i7gjZhkVlhc:TCbKfvQ6Ek4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=i7gjZhkVlhc:TCbKfvQ6Ek4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=i7gjZhkVlhc:TCbKfvQ6Ek4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=i7gjZhkVlhc:TCbKfvQ6Ek4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=i7gjZhkVlhc:TCbKfvQ6Ek4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=i7gjZhkVlhc:TCbKfvQ6Ek4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,0aa76e13-9130-4044-b16c-ecf2fc46e58f.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/NewClassesInTheLineup.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=49140780-5f83-46da-8079-e6389a39a490</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,49140780-5f83-46da-8079-e6389a39a490.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,49140780-5f83-46da-8079-e6389a39a490.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=49140780-5f83-46da-8079-e6389a39a490</wfw:commentRss>
      
      <title>Default button semantics in Silverlight revisited</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,49140780-5f83-46da-8079-e6389a39a490.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/nuSlYxSE0VM/DefaultButtonSemanticsInSilverlightRevisited.aspx</link>
      <pubDate>Thu, 11 Jun 2009 19:03:22 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
A month or so ago I posted on a &lt;a href="http://www.cauldwell.net/patrick/blog/ALdquodefaultButtonrdquoInSilverlight.aspx"&gt;solution&lt;/a&gt; for&#xD;
simulating “default button” semantics in a Silverlight app, meaning that if you are&#xD;
entering text in a text box and you hit the enter key, the “default button” for the&#xD;
“page” should be pressed.  Very natural for form entry, etc.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
An issue came up (discovered by &lt;a href="http://johnpapa.net/"&gt;John Papa&lt;/a&gt;) with&#xD;
the solution in a Prism app, because my solution depends on being able to find the&#xD;
“default” button in the visual tree using the FindName method.  That means that&#xD;
you have to be high enough up the visual tree to find the button, since it only works&#xD;
“down” the tree.  In a Prism app, it’s not necessarily clear where “high enough”&#xD;
might be.  Plus, because the solution requires unique names, and Prism modules&#xD;
may have nothing to do with one another, they may have duplicate names, etc.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Here’s a revision to the solution that doesn’t require unique names, and doesn’t require&#xD;
any static references that might interfere with proper garbage collection… &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
First, a new object called DefaultButtonHub that keeps track of the relationship between&#xD;
text boxes and buttons.  It also exposes an Attached Property that takes a DefaultButtonHub&#xD;
reference so we can hook up text boxes and buttons to the “hub” in XAML.&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:4c5596a4-5334-43ea-a5fc-014754ff037a" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;public class DefaultButtonHub&#xD;
{&#xD;
   ButtonAutomationPeer peer = null;&#xD;
&#xD;
   private void Attach(DependencyObject source)&#xD;
   {&#xD;
       if (source is Button)&#xD;
       {&#xD;
           peer = new ButtonAutomationPeer(source as Button);&#xD;
       }&#xD;
       else if (source is TextBox)&#xD;
       {&#xD;
           TextBox tb = source as TextBox;&#xD;
           tb.KeyUp += OnKeyUp;&#xD;
       }&#xD;
       else if (source is PasswordBox)&#xD;
       {&#xD;
           PasswordBox pb = source as PasswordBox;&#xD;
           pb.KeyUp += OnKeyUp;&#xD;
       }&#xD;
   }&#xD;
&#xD;
   private void OnKeyUp(object sender, KeyEventArgs arg)&#xD;
   {&#xD;
       if(arg.Key == Key.Enter)&#xD;
           if (peer != null)&#xD;
               ((IInvokeProvider)peer).Invoke();&#xD;
   }&#xD;
&#xD;
   public static DefaultButtonHub GetDefaultHub(DependencyObject obj)&#xD;
   {&#xD;
       return (DefaultButtonHub)obj.GetValue(DefaultHubProperty);&#xD;
   }&#xD;
&#xD;
   public static void SetDefaultHub(DependencyObject obj, DefaultButtonHub value)&#xD;
   {&#xD;
       obj.SetValue(DefaultHubProperty, value);&#xD;
   }&#xD;
&#xD;
   // Using a DependencyProperty as the backing store for DefaultHub.  This enables animation, styling, binding, etc...&#xD;
   public static readonly DependencyProperty DefaultHubProperty =&#xD;
       DependencyProperty.RegisterAttached("DefaultHub", typeof(DefaultButtonHub), typeof(DefaultButtonHub), new PropertyMetadata(OnHubAttach));&#xD;
&#xD;
   private static void OnHubAttach(DependencyObject source, DependencyPropertyChangedEventArgs prop)&#xD;
   {&#xD;
       DefaultButtonHub hub = prop.NewValue as DefaultButtonHub;&#xD;
       hub.Attach(source);&#xD;
   }&#xD;
&#xD;
}&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
Basically we’re expecting that both the text boxes and the button will register themselves&#xD;
with the “hub”.  If it’s a button that’s being registered, we wrap it in a ButtonAutomationPeer&#xD;
so we can “press” it later.  If it’s a text box, we hook up a KeyUp handler that&#xD;
will “press” the button if it’s there.  The requirement in the XAML is only marginally&#xD;
heavier than in my previous solution…we have to add a resource of type DefaultButtonHub,&#xD;
and point the button and text boxes at it using the {StaticResource} markup extension.&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:28f99d3a-6b2a-4ff1-8c7c-a058329caeb0" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: xml; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;&amp;lt;UserControl x:Class="DefaultButton.Page"&#xD;
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" &#xD;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" &#xD;
    xmlns:my="clr-namespace:DefaultButton"&#xD;
    Width="400" Height="300"&amp;gt;&#xD;
    &amp;lt;UserControl.Resources&amp;gt;&#xD;
        &amp;lt;my:DefaultButtonHub x:Key="defaultHub"/&amp;gt;&#xD;
    &amp;lt;/UserControl.Resources&amp;gt;&#xD;
    &amp;lt;Grid x:Name="LayoutRoot" Background="White"&amp;gt;&#xD;
        &amp;lt;Grid.RowDefinitions&amp;gt;&#xD;
            &amp;lt;RowDefinition/&amp;gt;&#xD;
            &amp;lt;RowDefinition/&amp;gt;&#xD;
        &amp;lt;/Grid.RowDefinitions&amp;gt;&#xD;
        &amp;lt;TextBox x:Name="theText" Grid.Row="0"&#xD;
                 my:DefaultButtonHub.DefaultHub="{StaticResource defaultHub}"/&amp;gt;&#xD;
        &amp;lt;Button x:Name="theButton" Grid.Row="1" Content="Default"&#xD;
                Click="theButton_Click" my:DefaultButtonHub.DefaultHub="{StaticResource defaultHub}"/&amp;gt;&#xD;
    &amp;lt;/Grid&amp;gt;&#xD;
&amp;lt;/UserControl&amp;gt;&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
Note that the new DefaultHub attached property is applied to both the text box and&#xD;
the button, each pointing the the single resource.  This way everything gets&#xD;
wired up property, there isn’t any problem with name resolution (aside from the usual&#xD;
resource name scoping) and everything will get cleaned up if the form needs to be&#xD;
GC’d.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=nuSlYxSE0VM:sVcydJmgFo8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=nuSlYxSE0VM:sVcydJmgFo8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=nuSlYxSE0VM:sVcydJmgFo8:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=nuSlYxSE0VM:sVcydJmgFo8:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=nuSlYxSE0VM:sVcydJmgFo8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=nuSlYxSE0VM:sVcydJmgFo8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=nuSlYxSE0VM:sVcydJmgFo8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=nuSlYxSE0VM:sVcydJmgFo8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=nuSlYxSE0VM:sVcydJmgFo8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,49140780-5f83-46da-8079-e6389a39a490.aspx</comments>
      <category>Silverlight</category>
      <category>Work</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/DefaultButtonSemanticsInSilverlightRevisited.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=c1dec284-c7c5-4742-b96e-22dcd1975d74</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,c1dec284-c7c5-4742-b96e-22dcd1975d74.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,c1dec284-c7c5-4742-b96e-22dcd1975d74.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=c1dec284-c7c5-4742-b96e-22dcd1975d74</wfw:commentRss>
      
      <title>RIA Services: the client side</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,c1dec284-c7c5-4742-b96e-22dcd1975d74.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/hwl9MogoDxw/RIAServicesTheClientSide.aspx</link>
      <pubDate>Fri, 05 Jun 2009 21:47:59 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Last &lt;a href="http://www.cauldwell.net/patrick/blog/NETRIAServicesFromScratch.aspx"&gt;time&lt;/a&gt;,&#xD;
I talked about how to build a Domain Service from scratch using whatever POCO you&#xD;
have lying around.  Now it’s time to talk about how that works on the client&#xD;
side…&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
One of the coolest things about RIA Services is that you don’t even have to “Add Service&#xD;
Reference…” to get a reference to the Domain Service.  If your Silverlight project&#xD;
is linked to the ASP.NET project correctly (see the RIA Services doc for how this&#xD;
works) the build steps will take care of generating the right code in your Silverlight&#xD;
project, and away you go.  There are several ways of accessing the service client-side,&#xD;
from dead-easy to a bit more involved.  We’ll start with dead easy.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The very easiest way to get things hooked up is to use the DomainDataSource control. &#xD;
It wraps your DomainDataContext (the client-side generated bit) with a data source&#xD;
you can bind directly against in XAML.&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:279e77b7-a94f-4eb3-b698-6c72bbf848a3" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: xml; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;&amp;lt;ria:DomainDataSource x:Name="PeopleDataSource" LoadMethodName="LoadPersons" AutoLoad="True"&amp;gt;&#xD;
  &amp;lt;ria:DomainDataSource.DomainContext&amp;gt;&#xD;
      &amp;lt;services:PeopleDomainContext/&amp;gt;&#xD;
  &amp;lt;/ria:DomainDataSource.DomainContext&amp;gt;&#xD;
&amp;lt;/ria:DomainDataSource&amp;gt;&#xD;
&amp;lt;dataControls:DataForm x:Name="dfPeople" CanUserAddItems="True" CanUserDeleteItems="true"&#xD;
                     ItemsSource="{Binding ElementName=PeopleDataSource, Path=Data}" &#xD;
                     ItemEditEnded="dfPeople_ItemEditEnded"&amp;gt;&#xD;
&amp;lt;/dataControls:DataForm&amp;gt;&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
The LoadMethodName attribute on the DomainDataSource tells it what method on the DomainContext&#xD;
to call in order to correctly populate the data context.  You can also pass parameters&#xD;
defined in XAML to the Load method if you only need to load a subset.  The DataForm&#xD;
control is bound to the Data property of the DomainDataSource, and away you go. &#xD;
You get this&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image.png"&gt;&#xD;
            &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_thumb.png" width="438" height="281"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Because the Insert/Update/Delete methods are implemented on the server-side DomainService,&#xD;
the DataForm automagically enables the edit, add and delete buttons at the top. &#xD;
If I edit or add a record, the save button shows up…&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_3.png"&gt;&#xD;
            &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_thumb_3.png" width="448" height="287"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Pressing either the Save or Cancel button fires the ItemEditEnded event, which we&#xD;
can grab to submit the changes back to the server&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:61ef5152-d951-4742-8042-f2981031a464" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;private void dfPeople_ItemEditEnded(object sender, DataFormItemEditEndedEventArgs e)&#xD;
{&#xD;
  if (e.EditAction == DataFormEditAction.Commit)&#xD;
      PeopleDataSource.SubmitChanges();&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
this is the very simplest case.  Calling SubmitChanges() here will send the edits/inserts&#xD;
up to the server right away.  For the sake of bandwidth, etc. I might want to&#xD;
implement my own “Save” button that batches up a whole set of change to the server&#xD;
rather than committing each edit individually.  You would still call PeopleDataSource.SubmitChanges,&#xD;
but not in response to the DataForm’s events.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
One of the great things about the way this works on the client side is that way the&#xD;
data validation attributes we set on the server-side POCO objects get propagated to&#xD;
the client.  For example, the server side LastName property looks like this (at&#xD;
least in the metadata class…)&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:a24de189-0bf0-4d3a-b486-9105fc6ade9e" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;[Required]&#xD;
[RegularExpression("[a-zA-z]*")]&#xD;
public string LastName;&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
The property that gets generated on the client side is&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:e47b1c66-9465-4a43-b623-55c64a8249ee" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;[DataMember()]&#xD;
[RegularExpression("[a-zA-z]*")]&#xD;
[Required()]&#xD;
public string LastName&#xD;
{&#xD;
  get&#xD;
  {&#xD;
      return this._lastName;&#xD;
  }&#xD;
  set&#xD;
  {&#xD;
      if ((this._lastName != value))&#xD;
      {&#xD;
          this.ValidateProperty("LastName", value);&#xD;
          this.RaiseDataMemberChanging("LastName");&#xD;
          this._lastName = value;&#xD;
          this.RaiseDataMemberChanged("LastName");&#xD;
      }&#xD;
  }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
It maintains the [Required] and [RegularExpression] attributes.  Plus, in the&#xD;
property setter, it calls ValidateProperty, which uses reflection to examine those&#xD;
attributes and throw validation exceptions if necessary.  By default, then, I&#xD;
get UI on the Silverlight client for validation.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_4.png"&gt;&#xD;
            &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_thumb_4.png" width="449" height="288"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The DataForm provides the UI around both the field in question and the summary at&#xD;
the bottom.  In this case, I probably don’t want to tell the user what RegEx&#xD;
I’m validating against, so I need to add the ErrorMessage property to the validation&#xD;
attribute&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:16a66730-1d71-416f-9f72-c73fc9f617aa" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;[Required]&#xD;
[RegularExpression("[a-zA-z]*", ErrorMessage="Alpha characters only please!")]&#xD;
public string LastName;&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_5.png"&gt;&#xD;
            &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_thumb_5.png" width="455" height="292"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
When that error is corrected and I press the Save button, the Custom Validation routine&#xD;
is applied (see &lt;a href="http://www.cauldwell.net/patrick/blog/NETRIAServicesFromScratch.aspx"&gt;last&#xD;
post&lt;/a&gt; for details)&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_6.png"&gt;&#xD;
            &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_thumb_6.png" width="463" height="297"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt; &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
When all the errors are corrected, and the save happens (and gets committed back to&#xD;
the server) the DataForm is updated to show the correct ID value (from the server)&#xD;
as well as the calculated Age property.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_7.png"&gt;&#xD;
            &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cauldwell.net/patrick/blog/images/RIAServicestheclientside_CFB3/image_thumb_7.png" width="466" height="299"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
For next to no work, I get a pretty good user experience for browsing, editing, inserting&#xD;
and deleting records.  If I wanted a bit more control, I could load the data&#xD;
into the DataContext myself, and then setup the databinding, rather than using the&#xD;
DomainDataSource in XAML&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:b239a716-d51d-4f0d-ab90-f9a97d4f0540" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;private PeopleDomainContext _context = new PeopleDomainContext();&#xD;
&#xD;
private void UserControl_Loaded(object sender, RoutedEventArgs e)&#xD;
{&#xD;
  if (_context.Persons.Count == 0)&#xD;
  {&#xD;
      _context.Loaded += (s, arg) =&amp;gt; loadPeople();&#xD;
      _context.LoadPersons();&#xD;
  }&#xD;
  else&#xD;
      loadPeople();&#xD;
}&#xD;
&#xD;
private void loadPeople()&#xD;
{&#xD;
  dfPeople.ItemsSource = _context.Persons;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
This would give me an opportunity to only load some people based on parameters, or&#xD;
whatever else I wanted to do to affect the loading of data before the data binding&#xD;
happens.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Next time… more cool things you can do with the DomainDataContext&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hwl9MogoDxw:C8F27QdBtss:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hwl9MogoDxw:C8F27QdBtss:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hwl9MogoDxw:C8F27QdBtss:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hwl9MogoDxw:C8F27QdBtss:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hwl9MogoDxw:C8F27QdBtss:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=hwl9MogoDxw:C8F27QdBtss:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hwl9MogoDxw:C8F27QdBtss:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=hwl9MogoDxw:C8F27QdBtss:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hwl9MogoDxw:C8F27QdBtss:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,c1dec284-c7c5-4742-b96e-22dcd1975d74.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/RIAServicesTheClientSide.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=7ac6946a-d494-433d-a0c2-5737ae2e9ee8</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,7ac6946a-d494-433d-a0c2-5737ae2e9ee8.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,7ac6946a-d494-433d-a0c2-5737ae2e9ee8.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=7ac6946a-d494-433d-a0c2-5737ae2e9ee8</wfw:commentRss>
      
      <title>.NET RIA Services from Scratch</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,7ac6946a-d494-433d-a0c2-5737ae2e9ee8.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/1l6mOwe5e98/NETRIAServicesFromScratch.aspx</link>
      <pubDate>Tue, 02 Jun 2009 22:53:18 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Most of the demos/samples I’ve looked at so far for &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;amp;displaylang=en"&gt;RIA&#xD;
Services&lt;/a&gt; have started with a LINQ to SQL or ADO.NET Entity model and generated&#xD;
Domain Service classes from those.  I decided to start from something super simple&#xD;
(a POCO, if you will) and work up from there.  I started with a canonical &#xD;
“Person” class&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:c0d7eccf-2fd5-43f8-8f63-1952d006701e" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;public partial class Person : INotifyPropertyChanged&#xD;
{&#xD;
   #region INotifyPropertyChanged Members&#xD;
&#xD;
   public event PropertyChangedEventHandler PropertyChanged;&#xD;
&#xD;
   #endregion&#xD;
&#xD;
   protected virtual void Changed(string propertyName)&#xD;
   {&#xD;
       PropertyChangedEventHandler handler = PropertyChanged;&#xD;
       if (handler != null)&#xD;
       {&#xD;
           handler(this, new PropertyChangedEventArgs(propertyName));&#xD;
       }&#xD;
   }&#xD;
&#xD;
   private int _personId;&#xD;
   public int PersonId&#xD;
   {&#xD;
       get&#xD;
       {&#xD;
           return _personId;&#xD;
       }&#xD;
       set&#xD;
       {&#xD;
           if (_personId != value)&#xD;
           {&#xD;
               _personId = value;&#xD;
               Changed("PersonId");&#xD;
           }&#xD;
       }&#xD;
   }&#xD;
&#xD;
   private string _firstName;&#xD;
   public string FirstName&#xD;
   {&#xD;
...&#xD;
   }&#xD;
   private string _lastName;&#xD;
   public string LastName&#xD;
   {&#xD;
...&#xD;
   }&#xD;
   private System.DateTime _birthDate;&#xD;
   public System.DateTime BirthDate&#xD;
   {&#xD;
...&#xD;
   }&#xD;
}&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
Nothing to see here.  It’s just a simple POCO that supports INotifyPropertyChanged&#xD;
for databinding.  Note that it’s a partial class…  The simplest path would&#xD;
be to add RIA Services attributes directly to these properties for things like data&#xD;
validation, but I wanted to try out all the features, so I split out the metadata&#xD;
into another file&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:70bb36b8-81ba-48fc-8512-e36482d4ed2e" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;[MetadataTypeAttribute(typeof(RiaServices.Web.Person.PersonMetadata))]&#xD;
public partial class Person&#xD;
{&#xD;
&#xD;
   internal sealed class PersonMetadata&#xD;
   {&#xD;
       [Key]&#xD;
       [Required]&#xD;
       public int PersonId;&#xD;
&#xD;
       [Required]&#xD;
       [RegularExpression("[a-zA-z]*")]&#xD;
       public string FirstName;&#xD;
&#xD;
       [Required]&#xD;
       [RegularExpression("[a-zA-z]*")]&#xD;
       public string LastName;&#xD;
&#xD;
       [Required]&#xD;
       public DateTime BirthDate;&#xD;
   }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
This is kind of an interesting trick, and allows me to separate out all the RIA specific&#xD;
metadata from the original class definition.  This makes total sense when you&#xD;
look at the way they handle LINQ to SQL, for example.  In that case you already&#xD;
have Entity classes defined by the LINQ to SQL wizard, so this extra metadata class&#xD;
allows you to associate the right attributes without touching the (generated) LINQ&#xD;
to SQL classes.  Clever.  Notice that the metadata class uses fields, not&#xD;
properties, and just matches the names for the sake of simplicity.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
In this case, the additional metadata defines data validation rules that get enforced&#xD;
both server and client side.  There are other attributes to enforcing string&#xD;
length and ranges.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
This all works because RIA Services generates “proxy” entity classes on the client&#xD;
side that are Silverlight compilable and also DataContracts (for serializing, which&#xD;
is cool…).  However, what happens if I have a calculated property that’s not&#xD;
just storage?  There’s a solution for that too, and it involves another piece&#xD;
of the partial class&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:09baa7be-63e0-47af-9d21-d18ecf0d1fcb" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;public partial class Person&#xD;
{&#xD;
   [Shared]&#xD;
   public int Age&#xD;
   {&#xD;
       get&#xD;
       {&#xD;
           this.Changed("Age");&#xD;
           return Convert.ToInt32(Math.Floor((DateTime.Now - _birthDate).Days / 365.25));&#xD;
       }&#xD;
   }&#xD;
&#xD;
}&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
This bit goes in a file called Person.shared.cs, and it will be copied to the client&#xD;
project and compiled there as well as on the server.  The [Shared] attribute&#xD;
marks the bits that need to be thus propagated.  Again, clever.  Of course,&#xD;
any such shared code has to compile in Silverlight.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The other piece of code I want to share (using the same method) is a custom validator. &#xD;
In addition to the [Required] or [RegularExpression] attributes used above, you can&#xD;
register a custom validation routine that can examine the state of the entity as a&#xD;
whole.  The validation routine looks like this&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:1eef0b66-a7ec-418b-b4d3-9bb6ac09199d" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;[Shared]&#xD;
public class PersonValidator&#xD;
{&#xD;
   public static bool IsPersonValid(Person p, ValidationContext context, out ValidationResult result)&#xD;
   {&#xD;
       bool valid = true;&#xD;
&#xD;
       result = null;&#xD;
&#xD;
       if (p.Age &amp;gt; 130)&#xD;
           valid = false;&#xD;
&#xD;
       if (!valid)&#xD;
       {&#xD;
           result = new ValidationResult("Birthdate is invalid, people can't be that old", new []{"BirthDate"});&#xD;
       }&#xD;
&#xD;
       return valid;&#xD;
&#xD;
   }&#xD;
}&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
That’s in a file called PersonValidator.shared.cs, so that it will be available client&#xD;
and server-side.  It’s associated with the Person entity with an additional attribute&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:d75e9da4-a94d-4440-b0ac-e9beb3db8ed7" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true; highlight: 1 ;"&gt;[CustomValidation(typeof(PersonValidator), "IsPersonValid")]&#xD;
[MetadataTypeAttribute(typeof(RiaServices.Web.Person.PersonMetadata))]&#xD;
public partial class Person&#xD;
...&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
With the Person entity all ready, I can expose it to the client by creating a new&#xD;
DomainService class with methods for Get, Insert, Update, Delete, etc.&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:9a554f7f-e2a6-4f0e-b838-7c7ee3bd3b71" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;[EnableClientAccess()]&#xD;
public class PeopleDomainService : DomainService&#xD;
{&#xD;
   public IQueryable&amp;lt;Person&amp;gt; GetPersons()&#xD;
   {&#xD;
&#xD;
       return PeopleData.Persons.AsQueryable&amp;lt;Person&amp;gt;();&#xD;
   }&#xD;
&#xD;
   public IQueryable&amp;lt;Person&amp;gt; GetPerson(int personId)&#xD;
   {&#xD;
       return (from p in PeopleData.Persons&#xD;
               where p.PersonId == personId&#xD;
               select p).AsQueryable&amp;lt;Person&amp;gt;();&#xD;
   }&#xD;
&#xD;
   public void UpdatePerson(Person person)&#xD;
   {&#xD;
       Person oldP = (from p in PeopleData.Persons&#xD;
                      where p.PersonId == person.PersonId&#xD;
                      select p).FirstOrDefault();&#xD;
&#xD;
       if (oldP != null)&#xD;
       {&#xD;
           PeopleData.Persons.Remove(oldP);&#xD;
           PeopleData.Persons.Add(person);&#xD;
       }&#xD;
   }&#xD;
&#xD;
   public void InsertPerson(Person person)&#xD;
   {&#xD;
       if (person.PersonId == 0)&#xD;
       {&#xD;
           int max = PeopleData.Persons.Max(p =&amp;gt; p.PersonId);&#xD;
           person.PersonId = max + 1;&#xD;
       }&#xD;
&#xD;
       PeopleData.Persons.Add(person);&#xD;
   }&#xD;
&#xD;
   public void DeletePerson(Person person)&#xD;
   {&#xD;
       Person oldP = (from p in PeopleData.Persons&#xD;
                      where p.PersonId == person.PersonId&#xD;
                      select p).FirstOrDefault();&#xD;
&#xD;
       if (oldP != null)&#xD;
       {&#xD;
           PeopleData.Persons.Remove(oldP);&#xD;
       }&#xD;
   }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
PeopleData.Persons in this case is a List&amp;lt;Person&amp;gt; that’s populated with some&#xD;
sample data.  The [EnableClientAccess] attribute causes the build-time bits to&#xD;
generate a client side proxy for calling the service without the client project needing&#xD;
a service reference.  It really makes the Silverlight and the Web projects feel&#xD;
like parts of the same app rather than disconnected pieces.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The corresponding class that is generated on the client side is a DomainDataContext,&#xD;
which feels much like a LINQ to SQL DataContext only it’s lazy-loaded like the Astoria&#xD;
ones.  The GetPersons method on the server results in LoadPersons on the client,&#xD;
etc.  If I hadn’t implemented the Insert/Update/Delete methods on the server&#xD;
side, the DomainDataContext would simple behave like a read only data source. &#xD;
This model works really well with the DataForm class.  If I set the ItemsSource&#xD;
of the DataForm to the Persons “table” in the client side data context, it will properly&#xD;
enable/disable the add/delete buttons depending on the capabilities of the data context. &#xD;
Neat.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Coming in future posts… hooking up the PersonDataContext to the Silverlight 3 UI,&#xD;
and in ASP.NET&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1l6mOwe5e98:h0VfHi1urng:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1l6mOwe5e98:h0VfHi1urng:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1l6mOwe5e98:h0VfHi1urng:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1l6mOwe5e98:h0VfHi1urng:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1l6mOwe5e98:h0VfHi1urng:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=1l6mOwe5e98:h0VfHi1urng:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1l6mOwe5e98:h0VfHi1urng:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=1l6mOwe5e98:h0VfHi1urng:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=1l6mOwe5e98:h0VfHi1urng:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,7ac6946a-d494-433d-a0c2-5737ae2e9ee8.aspx</comments>
      <category>RIA Services</category>
      <category>Silverlight</category>
      <category>Work</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/NETRIAServicesFromScratch.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=064786e2-4c83-47e5-b897-b276f428c781</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,064786e2-4c83-47e5-b897-b276f428c781.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,064786e2-4c83-47e5-b897-b276f428c781.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=064786e2-4c83-47e5-b897-b276f428c781</wfw:commentRss>
      
      <title>Silverlight: Taking it on the road</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,064786e2-4c83-47e5-b897-b276f428c781.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/0AaXE3E8fdg/SilverlightTakingItOnTheRoad.aspx</link>
      <pubDate>Thu, 28 May 2009 23:38:16 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Shaun and I will be doing a one-day training, “&lt;a href="http://events.sftsrc.com/EventDescription.aspx?EventId=1062&amp;amp;AbstractId=681"&gt;Practical&#xD;
Silverlight 3&lt;/a&gt;”, in lovely San Francisco, CA on July 8th.  It’s a full day&#xD;
of Silverlighty goodness, starting with the basics and movin’ on up.  We like&#xD;
to think of it as a 300 level technical introduction to the subject, so you will come&#xD;
away with a better understanding of the fundamentals, and where to look next.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Topics include&#xD;
&lt;/p&gt;&#xD;
        &lt;ul&gt;&#xD;
          &lt;li&gt;&#xD;
An introduction to Silverlight 3&lt;/li&gt;&#xD;
          &lt;li&gt;&#xD;
All about controls (styling, templating, building your own)&lt;/li&gt;&#xD;
          &lt;li&gt;&#xD;
Integrating with the browser&lt;/li&gt;&#xD;
          &lt;li&gt;&#xD;
Communicating with the server via WCF, REST/POX, Sockets, you name it&lt;/li&gt;&#xD;
        &lt;/ul&gt;&#xD;
        &lt;p&gt;&#xD;
If you are or will be in NorCal, come check it out.  It’s a good introduction&#xD;
for a very reasonable price.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=0AaXE3E8fdg:9MF1Ssy5KC4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=0AaXE3E8fdg:9MF1Ssy5KC4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=0AaXE3E8fdg:9MF1Ssy5KC4:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=0AaXE3E8fdg:9MF1Ssy5KC4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=0AaXE3E8fdg:9MF1Ssy5KC4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=0AaXE3E8fdg:9MF1Ssy5KC4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=0AaXE3E8fdg:9MF1Ssy5KC4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=0AaXE3E8fdg:9MF1Ssy5KC4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=0AaXE3E8fdg:9MF1Ssy5KC4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,064786e2-4c83-47e5-b897-b276f428c781.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/SilverlightTakingItOnTheRoad.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=6594227c-d582-4e66-98ef-be3bc0a5244c</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,6594227c-d582-4e66-98ef-be3bc0a5244c.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,6594227c-d582-4e66-98ef-be3bc0a5244c.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=6594227c-d582-4e66-98ef-be3bc0a5244c</wfw:commentRss>
      
      <title>Debugging session at PDX Code Camp</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,6594227c-d582-4e66-98ef-be3bc0a5244c.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/S0msRNL6pzc/DebuggingSessionAtPDXCodeCamp.aspx</link>
      <pubDate>Tue, 26 May 2009 20:51:11 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.sftsrc.com"&gt;SoftSource&lt;/a&gt; developer &lt;a href="http://www.debuggingblog.com"&gt;Prashant&#xD;
Sinha&lt;/a&gt; is going to be presenting on &lt;a href="http://portlandcodecamp.org/session.aspx?sid=3dd15647-a032-4448-b259-70728b23ad14"&gt;“Production&#xD;
Debugging for Silverlight and ASP.NET”&lt;/a&gt; at Code Camp.  Prashant is a debugging&#xD;
wiz, and teaches our two-day .NET debugging course, so this should be a very useful&#xD;
session.  &#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=S0msRNL6pzc:wYmateN-K8E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=S0msRNL6pzc:wYmateN-K8E:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=S0msRNL6pzc:wYmateN-K8E:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=S0msRNL6pzc:wYmateN-K8E:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=S0msRNL6pzc:wYmateN-K8E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=S0msRNL6pzc:wYmateN-K8E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=S0msRNL6pzc:wYmateN-K8E:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=S0msRNL6pzc:wYmateN-K8E:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=S0msRNL6pzc:wYmateN-K8E:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,6594227c-d582-4e66-98ef-be3bc0a5244c.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/DebuggingSessionAtPDXCodeCamp.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=4864bfbe-c60e-4829-b092-092ed46cde82</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,4864bfbe-c60e-4829-b092-092ed46cde82.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,4864bfbe-c60e-4829-b092-092ed46cde82.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=4864bfbe-c60e-4829-b092-092ed46cde82</wfw:commentRss>
      
      <title>Code Contracts</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,4864bfbe-c60e-4829-b092-092ed46cde82.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/Shz8JXaDF3Y/CodeContracts.aspx</link>
      <pubDate>Thu, 21 May 2009 21:50:38 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
In my &lt;a href="http://www.amazon.com/dp/0470259248?tag=patricvikkica-20&amp;amp;camp=14573&amp;amp;creative=327641&amp;amp;linkCode=as1&amp;amp;creativeASIN=0470259248&amp;amp;adid=0806NXZ2A5V5VPGTAE5D&amp;amp;"&gt;book&lt;/a&gt;,&#xD;
I talked a bit about programming by contract and how that makes everyone’s lives easier. &#xD;
Say I have a method that divides one integer by another&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:dfce7d2c-7373-4959-ae45-84cf2ae78204" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;public double Divide(int dividend, int divisor)&#xD;
{&#xD;
  return dividend / divisor;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
I’d like to be able to let callers know that they can’t pass a 0 for the divisor,&#xD;
because that will result in a DivideByZeroException, and nobody wants that. &#xD;
In the past I had a couple of choices on how to express that, mostly involving writing&#xD;
different kids of code, because C# doesn’t have a native expression of design by contract&#xD;
like Eiffel does.  One way is to use Debug.Assert&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:225e6e36-d5f2-417d-99bd-9aa339fc66a2" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;public double Divide(int dividend, int divisor)&#xD;
{&#xD;
  Debug.Assert(divisor != 0);&#xD;
&#xD;
  return dividend / divisor;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
That way any caller that passes a 0 will get an assertion dialog at runtime, which&#xD;
brings it pretty dramatically to everyone’s attention.  The assumption is that&#xD;
using the Debug.Assert will flush out all cases where people are incorrectly calling&#xD;
my method during development, so it’s OK that the assertion will get compiled out&#xD;
of my Release build.  However, that doesn’t make it impossible for a caller to&#xD;
pass a 0 at runtime and cause the exception.  Another option is explicitly checking&#xD;
parameters and throwing a different exception.&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:15cc7a83-ea90-4d71-a05e-4f361652cc58" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;public double Divide(int dividend, int divisor)&#xD;
{&#xD;
  if (divisor == 0)&#xD;
      throw new ArgumentException("divisor cannot be zero", "divisor");&#xD;
&#xD;
  return dividend / divisor;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2009/05/17/book-review-code-leader-by-patrick-cauldwell-a-digression-on-contracts.aspx"&gt;Patrick&lt;/a&gt; argues&#xD;
that this has now moved from defining contract to defining behavior, and I can agree&#xD;
with that, although I’d probably argue that it defines both contract and behavior&#xD;
since I’ve extended the functionality of the Debug.Assert to the release build, while&#xD;
also protecting my internal state from bad data.  But that’s really a separate&#xD;
discussion… :)&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Now thanks to the &lt;a href="http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx"&gt;Microsoft&#xD;
Code Contracts&lt;/a&gt; project, I have a third option.  The Code Contracts project&#xD;
is the evolution of the work done on Spec#, but in a language neutral way.  The&#xD;
Code Contracts tools are currently available from DevLabs for VS 2008, as well as&#xD;
shipping with VS 2010 B 1.  Just at the moment, there are more features in the&#xD;
DevLabs version that what made it into the 2010 beta.  With Code Contracts, I&#xD;
can rewrite my Divide method like this&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:de17865f-a475-4949-9f7c-68013b211d3e" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;public double Divide(int dividend, int divisor)&#xD;
{&#xD;
  Contract.Requires(divisor != 0);&#xD;
&#xD;
  return dividend / divisor;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
I like the syntax, as it calls out quite explicitly that I’m talking about contract,&#xD;
and making an explicit requirement.  The default behavior of this method at runtime&#xD;
is identical to Debug.Assert, it brings up an assertion dialog and brings everything&#xD;
to a screeching halt. However, it’s configurable at build time, so I can have it throw&#xD;
exceptions instead, or do whatever might be appropriate for my environment if the&#xD;
contract is violated.  I can even get the best of both worlds, with a generic&#xD;
version of Requires that specifies an exception&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:80a3b1b7-94eb-4dfe-bc89-1895ef757aa9" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;public double Divide(int dividend, int divisor)&#xD;
{&#xD;
  Contract.Requires&amp;lt;ArgumentException&amp;gt;(divisor != 0, "divisor");&#xD;
&#xD;
  return dividend / divisor;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
I could configure this to bring up the assertion dialog in Debug builds, but throw&#xD;
ArgumentNullException in Release builds.  Good stuff. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The example above demonstrates a required “precondition”.  With Code Contracts,&#xD;
I can also specify “postconditions”.  &#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:640f428b-ea7b-4994-8b7f-389e352dbb36" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;public void Transfer(Account from, Account to, decimal amount)&#xD;
{&#xD;
  Contract.Requires(from != null);&#xD;
  Contract.Requires(to != null);&#xD;
  Contract.Requires(amount &amp;gt; 0);&#xD;
  Contract.Ensures(from.Balance &amp;gt;= 0);&#xD;
&#xD;
  if (from.Balance &amp;lt; 0 || from.Balance &amp;lt; amount)&#xD;
      throw new InsufficientFundsException();&#xD;
&#xD;
  from.Balance -= amount;&#xD;
  to.Balance += amount;&#xD;
&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
This isn’t the greatest example, but basically the Transfer method is promising (with&#xD;
the Contract.Ensures method) that it won’t ever leave the Balance a negative number. &#xD;
Again, this is arguably behavior rather than contract, but you get the point.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
A really nifty feature is that I can write an interface definition and associate it&#xD;
with a set of contract calls, so that anyone who implements the interface will automatically&#xD;
“inherit” the contract validation.  The syntax is a bit weird, but you can see&#xD;
why it would need to be like this…&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:6aaea4a2-2c02-43ae-bf54-2609c119a94e" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;[ContractClass(typeof(ContractForCalucluator))]&#xD;
interface ICalculator&#xD;
{&#xD;
   int Add(int op1, int op2);&#xD;
   double Divide(int dividend, int divisor);&#xD;
}&#xD;
&#xD;
[ContractClassFor(typeof(ICalculator))]&#xD;
class ContractForCalucluator : ICalculator&#xD;
{&#xD;
   #region ICalculator Members&#xD;
&#xD;
   public int Add(int op1, int op2)&#xD;
   {&#xD;
       return default(int);&#xD;
   }&#xD;
&#xD;
   public double Divide(int dividend, int divisor)&#xD;
   {&#xD;
       Contract.Requires(divisor != 0);&#xD;
&#xD;
       return default(double);&#xD;
   }&#xD;
&#xD;
   #endregion&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
Now any class that implements ICalculator will have the contract validated for the&#xD;
Divide method.  Cool.  The last thing I want to point out is that the team&#xD;
included a handy sample of how to work with contract validation in your MSTest unit&#xD;
test code.  The Contract class exposes an event called ContractFailed, and I&#xD;
can subscribe to the event to decide what happens on a failure.  For a test assembly,&#xD;
I can do this&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:2d2c7b05-8398-467c-b1d1-ddeef3b7fb8b" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;[AssemblyInitialize]&#xD;
public static void AssemblyInitialize(TestContext tc)&#xD;
{&#xD;
  Contract.ContractFailed += (sender, e) =&amp;gt;&#xD;
  {&#xD;
      e.SetHandled();&#xD;
      e.SetUnwind();&#xD;
      Assert.Fail(e.FailureKind.ToString() + " : " + e.Message);&#xD;
  };&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
which will translate contract failures into test failures with very explicit error&#xD;
messages.  In the case of my Divide method if I run this test&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:5727431d-7999-4bd2-94ec-eec819769016" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "&gt;[TestMethod()]&#xD;
public void DivideContractViolation()&#xD;
{&#xD;
  Calculator target = new Calculator(); &#xD;
  int dividend = 12; &#xD;
  int divisor = 0; &#xD;
  double actual;&#xD;
  actual = target.Divide(dividend, divisor);&#xD;
  Assert.Fail("Should have failed");&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
I get a test failure of&#xD;
&lt;/p&gt;&#xD;
        &lt;blockquote&gt;&#xD;
          &lt;p&gt;&#xD;
Test method CalculatorTests.CalculatorTest.DivideContractViolation threw exception: &#xD;
System.Diagnostics.Contracts.ContractException: Precondition failed: divisor != 0&#xD;
divisor ---&amp;gt;  Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException:&#xD;
Assert.Fail failed. Precondition : Precondition failed: divisor != 0 divisor.&#xD;
&lt;/p&gt;&#xD;
        &lt;/blockquote&gt;&#xD;
        &lt;p&gt;&#xD;
Cool.  This is definitely something I’ll be looking at more in the future.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Shz8JXaDF3Y:Zn4HD2hl8X8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Shz8JXaDF3Y:Zn4HD2hl8X8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Shz8JXaDF3Y:Zn4HD2hl8X8:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Shz8JXaDF3Y:Zn4HD2hl8X8:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Shz8JXaDF3Y:Zn4HD2hl8X8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=Shz8JXaDF3Y:Zn4HD2hl8X8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Shz8JXaDF3Y:Zn4HD2hl8X8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=Shz8JXaDF3Y:Zn4HD2hl8X8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Shz8JXaDF3Y:Zn4HD2hl8X8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,4864bfbe-c60e-4829-b092-092ed46cde82.aspx</comments>
      <category>Code Construction</category>
      <category>Testing</category>
      <category>Work</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/CodeContracts.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=ff37319d-3c19-42ad-abe7-0a7be61b317e</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,ff37319d-3c19-42ad-abe7-0a7be61b317e.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,ff37319d-3c19-42ad-abe7-0a7be61b317e.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ff37319d-3c19-42ad-abe7-0a7be61b317e</wfw:commentRss>
      
      <title>PDX Code Camp is coming up&amp;hellip;</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,ff37319d-3c19-42ad-abe7-0a7be61b317e.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/jO61OXw5-oE/PDXCodeCampIsComingUphellip.aspx</link>
      <pubDate>Wed, 20 May 2009 20:45:43 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Not this weekend but next (5/30) is &lt;a href="http://portlandcodecamp.org"&gt;PDX Code&#xD;
Camp 2009&lt;/a&gt;.  A whole day of free software learning and general nerdy hanging&#xD;
out.  I’ll be talking about building business apps in Silverlight 3, and my &lt;a href="http://www.sftsrc.com"&gt;SoftSource&lt;/a&gt; compadre&#xD;
Tim Johnson is going to be talking about making your web application more accessible&#xD;
for people with disabilities.  There are also a host of other sessions including&#xD;
some big names like Ward Cunningham, so it’s an event not to be missed, and cheap&#xD;
at twice the price!&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jO61OXw5-oE:rXZJW8uJ-10:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jO61OXw5-oE:rXZJW8uJ-10:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jO61OXw5-oE:rXZJW8uJ-10:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jO61OXw5-oE:rXZJW8uJ-10:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jO61OXw5-oE:rXZJW8uJ-10:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=jO61OXw5-oE:rXZJW8uJ-10:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jO61OXw5-oE:rXZJW8uJ-10:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=jO61OXw5-oE:rXZJW8uJ-10:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=jO61OXw5-oE:rXZJW8uJ-10:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,ff37319d-3c19-42ad-abe7-0a7be61b317e.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/PDXCodeCampIsComingUphellip.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=fa25181c-c4a7-4d8b-947a-6d14bc07ee12</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,fa25181c-c4a7-4d8b-947a-6d14bc07ee12.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,fa25181c-c4a7-4d8b-947a-6d14bc07ee12.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=fa25181c-c4a7-4d8b-947a-6d14bc07ee12</wfw:commentRss>
      
      <title>LINQ: joining data in memory with data in SQL Server</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,fa25181c-c4a7-4d8b-947a-6d14bc07ee12.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/Latf-7CnWEc/LINQJoiningDataInMemoryWithDataInSQLServer.aspx</link>
      <pubDate>Wed, 20 May 2009 20:38:43 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
This came up in class yesterday, so I did a little digging.  Everyone may already&#xD;
know this, but it came as news to me. :)&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If I’ve got a collection in memory, as well as a LINQ to SQL DataContext&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:863b2a97-d5bd-42de-87fa-dfdd99572795" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;List&amp;lt;FavoriteFood&amp;gt; foods = new List&amp;lt;FavoriteFood&amp;gt;(){&#xD;
	new FavoriteFood{CustomerID = "ALFKI", Favorite="Chips"},&#xD;
	new FavoriteFood{CustomerID = "ANATR", Favorite = "Fish"}};&#xD;
&#xD;
NorthwindDataContext context = new NorthwindDataContext();&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
and I want to do an INNER JOIN between the &lt;code&gt;foods&lt;/code&gt; list and the Customer&#xD;
table in Northwind, it would seem like this should do it&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:14223c48-ead8-4350-ac80-44224c210c41" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;var bad = (from cust in context.Customers&#xD;
         join f in foods on cust.CustomerID equals f.CustomerID&#xD;
         select new&#xD;
         {&#xD;
             cust.ContactName,&#xD;
             f.Favorite&#xD;
         }).ToList();&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
but sadly, no.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.cauldwell.net/patrick/blog/images/LINQjoiningdatainmemorywithdatainSQLServ_BF72/image.png"&gt;&#xD;
            &lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://www.cauldwell.net/patrick/blog/images/LINQjoiningdatainmemorywithdatainSQLServ_BF72/image_thumb.png" border="0" width="419" height="258"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
if you stop to think about it, it totally makes sense that it wouldn’t work like that,&#xD;
since there’s no way to translate that into SQL in any rational way to send to SQL&#xD;
server.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
OK, so the next step would be to first get the customers in memory, then do the join&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:991fb98d-884f-407f-b472-8e82fc69b354" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;//this executes the whole query, thus retrieving the entire customer table&#xD;
var customers = (from c in context.Customers&#xD;
             select c).ToList();&#xD;
&#xD;
//an inner join between the customers from SQL and the in-memory list&#xD;
var inner = from cust in customers&#xD;
     join f in foods on cust.CustomerID equals f.CustomerID&#xD;
     select new&#xD;
     {&#xD;
         cust.ContactName,&#xD;
         f.Favorite&#xD;
     };&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
That works, but I’ve had to pull the entire Customer table into memory just to join&#xD;
two rows.  If I wanted to do a LEFT OUTER JOIN, I’d need that anyway, like so&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:70268c0d-75a2-4c83-bf0e-df7eb45d01c3" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;//here's the left outer join between the customer list from SQL &#xD;
//and the in-memory favorites&#xD;
var leftouter = from cust in customers&#xD;
             join f in foods on cust.CustomerID equals f.CustomerID into custFoods&#xD;
             from custFood in custFoods.DefaultIfEmpty()&#xD;
             select new&#xD;
             {&#xD;
                 cust.ContactName,&#xD;
                 Favorite = custFood == null ? null : custFood.Favorite&#xD;
             };&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
but I want an inner join without pulling down all the customers, so I need to only&#xD;
fetch those rows that will join from Customer&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:26850cad-8cbd-4d00-b6b4-37cf6151d284" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;//this is how you manage the IN clause&#xD;
var x = from c1 in context.Customers&#xD;
     where (from cf in foods&#xD;
           select cf.CustomerID).Contains(c1.CustomerID)&#xD;
     select c1;&#xD;
&#xD;
//Note that to join the result in x back to the foods collection you would have to &#xD;
//execute the query just like with customers above...&#xD;
var littleInnerJoin = from filteredCustomer in x.ToList()&#xD;
                   join f in foods on filteredCustomer.CustomerID equals f.CustomerID&#xD;
                   select new&#xD;
                       {&#xD;
                           filteredCustomer.ContactName,&#xD;
                           f.Favorite&#xD;
                       };&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
It’s two steps, but now I’ve just loaded the rows that will join into memory, and&#xD;
then done the join with LINQ to Objects.  It bears a little thinking about, but&#xD;
doesn’t seem like too much overhead, IMHO.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Latf-7CnWEc:uecXFuwkDTY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Latf-7CnWEc:uecXFuwkDTY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Latf-7CnWEc:uecXFuwkDTY:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Latf-7CnWEc:uecXFuwkDTY:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Latf-7CnWEc:uecXFuwkDTY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=Latf-7CnWEc:uecXFuwkDTY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Latf-7CnWEc:uecXFuwkDTY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=Latf-7CnWEc:uecXFuwkDTY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=Latf-7CnWEc:uecXFuwkDTY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,fa25181c-c4a7-4d8b-947a-6d14bc07ee12.aspx</comments>
      <category>Work</category>
      <category>LINQ</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/LINQJoiningDataInMemoryWithDataInSQLServer.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=94fb91a2-2c6c-422f-a48e-3f46aabcd8a2</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,94fb91a2-2c6c-422f-a48e-3f46aabcd8a2.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,94fb91a2-2c6c-422f-a48e-3f46aabcd8a2.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=94fb91a2-2c6c-422f-a48e-3f46aabcd8a2</wfw:commentRss>
      
      <title>A &amp;ldquo;default button&amp;rdquo; in Silverlight</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,94fb91a2-2c6c-422f-a48e-3f46aabcd8a2.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/8YQEx5PKfD8/ALdquodefaultButtonrdquoInSilverlight.aspx</link>
      <pubDate>Thu, 07 May 2009 20:27:54 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Let’s say I’ve got to the effort of creating a modal dialog or it’s equivalent in&#xD;
a Silverlight application.  What I would like to complete the picture is a “default”&#xD;
button, so that if I hit the Enter key while in a text box, the dialog will be “submitted”. &#xD;
There are probably several ways of achieving this end, but I wanted something that&#xD;
was simple, and encapsulated in an attached property so the consumer wouldn’t have&#xD;
to deal with much code.  I wrote the attached property so that I could use it&#xD;
on text boxes like this&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:53e11dba-4d3e-4301-8129-6611a235d4fe" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: xml; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;&amp;lt;TextBox x:Name="theText" VerticalAlignment="Center" Margin="10,0,10,0" &#xD;
	Grid.Row="0" my:DefaultButtonService.DefaultButton="theButton"/&amp;gt;&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
where “theButton” here is the default button I want to be pressed when the Enter key&#xD;
happens inside my text box.  The downside is that I have to apply this property&#xD;
to every text box on the page, but so be it, that seems like a relatively small price&#xD;
to pay.  So I got as far as finding the named button in the visual tree, but&#xD;
the the question was, how to “press” the button.  The Button class in Silverlight&#xD;
has a protected OnClick that would do the trick, if it wasn’t protected.  I could&#xD;
derive my own control from Button and expose the OnClick method, but ewww.  If&#xD;
I did that then every dialog that wanted this behavior would have to remember to use&#xD;
the derived Button class.  I tried reflecting over the Button and Invoking OnClick&#xD;
anyway, but turns out you get a security exception.  OK.  Then, thanks to&#xD;
a presentation &lt;a href="http://blogs.sftsrc.com/stuart/Default.aspx"&gt;Stuart&lt;/a&gt; gave&#xD;
us yesterday on Accessibility, I remembered the Automation framework in Silverlight. &#xD;
That turned out to be super easy, just create an instance of ButtonAutmationPeer from&#xD;
the Button, then Invoke it.  Cool.&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:77a2e41a-7d86-4263-9298-977c8aeb4971" class="wlWriterEditableSmartContent"&gt;&#xD;
          &lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4; toolbar: true;"&gt;public static class DefaultButtonService&#xD;
{&#xD;
   public static readonly DependencyProperty DefaultButtonProperty =&#xD;
       DependencyProperty.RegisterAttached("DefaultButton", typeof(string), typeof(DefaultButtonService), new PropertyMetadata(OnDefaultButtonChanged));&#xD;
&#xD;
&#xD;
   public static string GetDefaultButton(DependencyObject d)&#xD;
   {&#xD;
       return (string)d.GetValue(DefaultButtonProperty);&#xD;
   }&#xD;
&#xD;
   /// &amp;lt;summary&amp;gt;&#xD;
   /// Sets the CommandParameter property.&#xD;
   /// &amp;lt;/summary&amp;gt;&#xD;
   public static void SetDefaultButton(DependencyObject d, string value)&#xD;
   {&#xD;
       d.SetValue(DefaultButtonProperty, value);&#xD;
   }&#xD;
&#xD;
   private static void OnDefaultButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)&#xD;
   {&#xD;
       TextBox tb = d as TextBox;&#xD;
       if (tb != null)&#xD;
       {&#xD;
           tb.KeyUp += new KeyEventHandler(tb_KeyUp);&#xD;
       }&#xD;
   }&#xD;
&#xD;
   static void tb_KeyUp(object sender, KeyEventArgs e)&#xD;
   {&#xD;
       switch (e.Key)&#xD;
       {&#xD;
           case Key.Enter:&#xD;
               string name = (string)((DependencyObject)sender).GetValue(DefaultButtonProperty);&#xD;
               object root = App.Current.RootVisual;&#xD;
               object button = ((FrameworkElement)root).FindName(name);&#xD;
               if (button is Button)&#xD;
               {&#xD;
                   ButtonAutomationPeer peer = new ButtonAutomationPeer((Button)button);&#xD;
&#xD;
                   IInvokeProvider ip = (IInvokeProvider)peer;&#xD;
                   ip.Invoke();&#xD;
               }&#xD;
               break;&#xD;
       }&#xD;
   }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
          &lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=8YQEx5PKfD8:Jj84y3IpwI0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=8YQEx5PKfD8:Jj84y3IpwI0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=8YQEx5PKfD8:Jj84y3IpwI0:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=8YQEx5PKfD8:Jj84y3IpwI0:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=8YQEx5PKfD8:Jj84y3IpwI0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=8YQEx5PKfD8:Jj84y3IpwI0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=8YQEx5PKfD8:Jj84y3IpwI0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=8YQEx5PKfD8:Jj84y3IpwI0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=8YQEx5PKfD8:Jj84y3IpwI0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,94fb91a2-2c6c-422f-a48e-3f46aabcd8a2.aspx</comments>
      <category>Silverlight</category>
      <category>Work</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/ALdquodefaultButtonrdquoInSilverlight.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=32617f89-fb84-46d3-a0de-cf028ba56521</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,32617f89-fb84-46d3-a0de-cf028ba56521.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,32617f89-fb84-46d3-a0de-cf028ba56521.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=32617f89-fb84-46d3-a0de-cf028ba56521</wfw:commentRss>
      
      <title>New one-day classes at SoftSource</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,32617f89-fb84-46d3-a0de-cf028ba56521.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/hOdTXB_mmxM/NewOnedayClassesAtSoftSource.aspx</link>
      <pubDate>Tue, 07 Apr 2009 17:41:19 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
We just added a set of new one day classes starting in May, including “Agile in day”,&#xD;
Silverlight 3, and UI design patterns for WPF and Silverlight.  These are lecture-style&#xD;
classes that will give you an in depth look at each subject.  Like our previous&#xD;
Silverlight event, these are 300-400 level, technical sessions that will give you&#xD;
a leg up on each subject in a day.  Because they are presented lecture style,&#xD;
we can offer them for only $125 each, so feel free to collect the whole set. :-) &#xD;
Details and registration &lt;a href="http://events.sftsrc.com/"&gt;here&lt;/a&gt;.  We may&#xD;
be adding some additional topics soon, so check back often.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hOdTXB_mmxM:1vVCt53__00:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hOdTXB_mmxM:1vVCt53__00:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hOdTXB_mmxM:1vVCt53__00:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hOdTXB_mmxM:1vVCt53__00:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hOdTXB_mmxM:1vVCt53__00:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=hOdTXB_mmxM:1vVCt53__00:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hOdTXB_mmxM:1vVCt53__00:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=hOdTXB_mmxM:1vVCt53__00:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=hOdTXB_mmxM:1vVCt53__00:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,32617f89-fb84-46d3-a0de-cf028ba56521.aspx</comments>
      <category>Silverlight</category>
      <category>training</category>
      <category>Work</category>
      <category>Agile</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/NewOnedayClassesAtSoftSource.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=7d4b00dc-ce68-44f3-a493-9d7073d3bcdd</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,7d4b00dc-ce68-44f3-a493-9d7073d3bcdd.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,7d4b00dc-ce68-44f3-a493-9d7073d3bcdd.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=7d4b00dc-ce68-44f3-a493-9d7073d3bcdd</wfw:commentRss>
      <slash:comments>1</slash:comments>
      
      <title>MIX 09 - Thursday</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,7d4b00dc-ce68-44f3-a493-9d7073d3bcdd.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/b4Fr7MpFNW0/MIX09Thursday.aspx</link>
      <pubDate>Thu, 19 Mar 2009 20:45:58 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;I'll probably have some more cogent things&#xD;
to say about it all in a few days, but my first set of takeaways as of mid-day Thursday: &#xD;
&lt;ul&gt;&lt;li&gt;&#xD;
Silverlight 3 solves many if not most of the downsides of working in Silverlight vs.&#xD;
WPF&lt;/li&gt;&lt;li&gt;&#xD;
Silverlight 3 + .NET RIA services totally removes any and all barriers to building&#xD;
business apps in Silverlight&lt;/li&gt;&lt;li&gt;&#xD;
.NET RIA services is the killer app we’ve been waiting for as far as building RIA&#xD;
apps is concerned.  it’s like Astoria, only better, and doesn’t require Entities&#xD;
(long live LINQ to SQL!).  &#xD;
&lt;/li&gt;&lt;li&gt;&#xD;
Blend 3 will revolutionize the way designers and developers work together, and make&#xD;
the design process much faster&lt;/li&gt;&lt;li&gt;&#xD;
Free martinis are both a blessing and a curse&lt;/li&gt;&lt;li&gt;&#xD;
Having a DJ at your keynotes is a fantastic idea&lt;/li&gt;&lt;li&gt;&#xD;
Not only would downtown Hillsboro (where I live) fit inside the Venetian, but you&#xD;
probably wouldn’t actually notice it.&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b4Fr7MpFNW0:K-bbJI6gTCA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b4Fr7MpFNW0:K-bbJI6gTCA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b4Fr7MpFNW0:K-bbJI6gTCA:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b4Fr7MpFNW0:K-bbJI6gTCA:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b4Fr7MpFNW0:K-bbJI6gTCA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=b4Fr7MpFNW0:K-bbJI6gTCA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b4Fr7MpFNW0:K-bbJI6gTCA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=b4Fr7MpFNW0:K-bbJI6gTCA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b4Fr7MpFNW0:K-bbJI6gTCA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,7d4b00dc-ce68-44f3-a493-9d7073d3bcdd.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/MIX09Thursday.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=b705c37b-b47f-4e8d-8f8b-091efc4cb684</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,b705c37b-b47f-4e8d-8f8b-091efc4cb684.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,b705c37b-b47f-4e8d-8f8b-091efc4cb684.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=b705c37b-b47f-4e8d-8f8b-091efc4cb684</wfw:commentRss>
      
      <title>Congratulations, you've installed dasBlog with Web Deploy!</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,b705c37b-b47f-4e8d-8f8b-091efc4cb684.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/03gSStqqwoY/CongratulationsYouveInstalledDasBlogWithWebDeploy.aspx</link>
      <pubDate>Wed, 11 Mar 2009 07:00:00 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
After &lt;a href="Login.aspx"&gt;logging in&lt;/a&gt;, be sure to visit all the options under &lt;a href="EditConfig.aspx"&gt;Configuration&lt;/a&gt; in&#xD;
the Admin Menu Bar above. There are &lt;a href="http://dasblog.info/ThemeScreenShots.aspx"&gt;26&#xD;
themes to choose from&lt;/a&gt;, and you can also &lt;a href="http://dasblog.info/ThemesAndMacros.aspx"&gt;create&#xD;
your own&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=03gSStqqwoY:4yJqgplojt4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=03gSStqqwoY:4yJqgplojt4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=03gSStqqwoY:4yJqgplojt4:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=03gSStqqwoY:4yJqgplojt4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=03gSStqqwoY:4yJqgplojt4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=03gSStqqwoY:4yJqgplojt4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=03gSStqqwoY:4yJqgplojt4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=03gSStqqwoY:4yJqgplojt4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=03gSStqqwoY:4yJqgplojt4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,b705c37b-b47f-4e8d-8f8b-091efc4cb684.aspx</comments>
      <category>dasBlog</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/CongratulationsYouveInstalledDasBlogWithWebDeploy.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=1b71604e-3348-423e-a127-8808e61db198</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,1b71604e-3348-423e-a127-8808e61db198.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,1b71604e-3348-423e-a127-8808e61db198.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=1b71604e-3348-423e-a127-8808e61db198</wfw:commentRss>
      
      <title>MVVM and a modal dialog</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,1b71604e-3348-423e-a127-8808e61db198.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/3kNDalxNp2A/MVVMAndAModalDialog.aspx</link>
      <pubDate>Tue, 10 Mar 2009 23:36:01 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
I’m building a MVVM app in WPF, and needed to show a modal dialog, but I couldn’t&#xD;
figure out how to make it work and still maintain the separation between ViewModels&#xD;
and Views.  I have been mapping Views to ViewModels using DataTemplates, so that&#xD;
the relationship is declarative in XAML rather than in code someplace.  What&#xD;
I ended up with was a new Window called Dialog that takes a type in its constructor&#xD;
that corresponds to a ViewModelBase-derived type.  (See &lt;a href="http://joshsmithonwpf.wordpress.com/"&gt;Josh&#xD;
Smith’s&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx"&gt;WPF Apps&#xD;
With The Model-View-ViewModel Design Pattern&lt;/a&gt; article for background on how the&#xD;
pieces fit together…)  &#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp"&gt;public partial class Dialog : Window&#xD;
{&#xD;
    public Dialog(Type vmType)&#xD;
    {&#xD;
        InitializeComponent();&#xD;
&#xD;
        ViewModelBase vmb = Activator.CreateInstance(vmType) as ViewModelBase;&#xD;
        &#xD;
        item.Content = vmb;&#xD;
&#xD;
        this.Title = vmb.DisplayName;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
In the XAML for Dialog, there’s just a Grid that contains a ContentPresenter called&#xD;
“item”.  The constructor sets item’s content to be the ViewModel, and the DataTemplate&#xD;
takes care of associating the View (a UserControl) with the ViewModel.  Note&#xD;
the use of &lt;code&gt;SizeToContent="WidthAndHeight"&lt;/code&gt; on the Dialog window, which&#xD;
causes the window to resize to how ever big the UserControl that represents the View&#xD;
might be.&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: xml"&gt;&amp;lt;Window x:Class="SomeNamespace.Dialog"&#xD;
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&#xD;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&#xD;
    Title="Dialog" SizeToContent="WidthAndHeight"&amp;gt;&#xD;
    &amp;lt;Grid&amp;gt;&#xD;
        &amp;lt;ContentPresenter x:Name="item"&amp;gt;&#xD;
            &#xD;
        &amp;lt;/ContentPresenter&amp;gt;&#xD;
    &amp;lt;/Grid&amp;gt;&#xD;
&amp;lt;/Window&amp;gt;&lt;/pre&gt;&#xD;
        &lt;pre class="brush: xml"&gt;&amp;lt;DataTemplate DataType="{x:Type vm:NewThingViewModel}"&amp;gt;&#xD;
    &amp;lt;vw:NewThing/&amp;gt;&#xD;
&amp;lt;/DataTemplate&amp;gt;&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
To create an instance of the new modal dialog, I just create a new instance of Dialog&#xD;
and pass the type of ViewModel it’s supposed to host…&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp"&gt;new Dialog(typeof(NewThingViewModel)).ShowDialog();&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
There are still some details to work out as far as getting results from said dialog,&#xD;
but hey, progress…&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=3kNDalxNp2A:z94GfSfENkU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=3kNDalxNp2A:z94GfSfENkU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=3kNDalxNp2A:z94GfSfENkU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=3kNDalxNp2A:z94GfSfENkU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=3kNDalxNp2A:z94GfSfENkU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=3kNDalxNp2A:z94GfSfENkU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=3kNDalxNp2A:z94GfSfENkU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=3kNDalxNp2A:z94GfSfENkU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=3kNDalxNp2A:z94GfSfENkU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,1b71604e-3348-423e-a127-8808e61db198.aspx</comments>
      <category>Work</category>
      <category>Design Patterns</category>
      <category>WPF</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/MVVMAndAModalDialog.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=b1aa6fe5-fa05-4171-b565-25a4062e31f6</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,b1aa6fe5-fa05-4171-b565-25a4062e31f6.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,b1aa6fe5-fa05-4171-b565-25a4062e31f6.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=b1aa6fe5-fa05-4171-b565-25a4062e31f6</wfw:commentRss>
      <slash:comments>3</slash:comments>
      
      <title>MVVM: binding to Commands in Silverlight</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,b1aa6fe5-fa05-4171-b565-25a4062e31f6.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/b2wl5XB4SBc/MVVMBindingToCommandsInSilverlight.aspx</link>
      <pubDate>Thu, 05 Mar 2009 00:06:59 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
So yesterday I was reading &lt;a href="http://joshsmithonwpf.wordpress.com/"&gt;Josh Smith’s&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx"&gt;WPF&#xD;
Apps With The Model-View-ViewModel Design Pattern&lt;/a&gt; article in last month’s MSDN&#xD;
magazine, and I really liked the sample app that he built.  It totally cleared&#xD;
up for me some rough edges (in my understanding) of MVVM.  Most specifically,&#xD;
I had been conflicted about where to put things like button click handlers. &#xD;
Do you put a Click event handler in your codebehind, which just defers to the View&#xD;
Model?  Do you create a generic CommandBinding handler to wire up commands to&#xD;
your View Model’s methods?  (I’ve seen both in various examples…)  The former&#xD;
seems like cheating a bit on MVVM (no code behind would be ideal, it seems to me)&#xD;
and the latter overly complicated.  Josh’s solution is to bind the Command property&#xD;
of the UIElement (button, menu item, whatever) to a property of type ICommand on the&#xD;
View Model.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
That totally made sense to me.  No more code behind (like at all, basically)&#xD;
and I don’t have to build additional framework to make it happen, with the exception&#xD;
of coming up with an ICommand implementation.  Josh solved that with a class&#xD;
he calls RelayCommand, which just wraps an ICommand implementation around a delegate&#xD;
(or lambda) of type Action&amp;lt;object&amp;gt;, with an optional Predicate&amp;lt;object&amp;gt;&#xD;
to handle the CanExecute method of ICommand.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Groovy, now my XAML knows absolutely nothing about the View Model, and it’s only links&#xD;
to said View Model are through data binding. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Then I got to wondering if something as easy could work in Silverlight…  The&#xD;
answer turned out to be almost, but not quite.  Since Silverlight controls don’t&#xD;
expose a Command property, you have to hook them up yourself, but otherwise it works&#xD;
just the same way.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
So if I’ve got a page with a single button on it&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.cauldwell.net/patrick/blog/images/MVVMbindingtoCommandsinSilverlight_E1BC/CropperCapture10.png"&gt;&#xD;
            &lt;img style="border-width: 0px; display: inline;" title="CropperCapture[10]" alt="CropperCapture[10]" src="http://www.cauldwell.net/patrick/blog/images/MVVMbindingtoCommandsinSilverlight_E1BC/CropperCapture10_thumb.png" border="0" width="244" height="186"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;pre class="brush: xml"&gt;&amp;lt;UserControl x:Class="SilverlightCommands.Page"&#xD;
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" &#xD;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" &#xD;
    xmlns:my="clr-namespace:SilverlightCommands"&#xD;
    Width="400" Height="300"&amp;gt;&#xD;
    &amp;lt;Grid x:Name="LayoutRoot" Background="White"&amp;gt;&#xD;
        &amp;lt;Button Content="Say Hello..." VerticalAlignment="Center" &#xD;
                HorizontalAlignment="Center" &#xD;
                my:ButtonService.Command="{Binding Path=SayHello}"/&amp;gt;&#xD;
    &amp;lt;/Grid&amp;gt;&#xD;
&amp;lt;/UserControl&amp;gt;&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
I can add an attached property whose value is bound to the ICommand property on the&#xD;
View Model.  The attached property grabs the ICommand and hooks up the button’s&#xD;
click handler to the ICommand’s Execute method.&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp"&gt;#region Command&#xD;
&#xD;
/// &amp;lt;summary&amp;gt;&#xD;
/// Command Attached Dependency Property&#xD;
/// &amp;lt;/summary&amp;gt;&#xD;
public static readonly DependencyProperty CommandProperty =&#xD;
    DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(ButtonService),&#xD;
        new PropertyMetadata(OnCommandChanged));&#xD;
&#xD;
/// &amp;lt;summary&amp;gt;&#xD;
/// Gets the Command property.&#xD;
/// &amp;lt;/summary&amp;gt;&#xD;
public static ICommand GetCommand(DependencyObject d)&#xD;
{&#xD;
    return (ICommand)d.GetValue(CommandProperty);&#xD;
}&#xD;
&#xD;
/// &amp;lt;summary&amp;gt;&#xD;
/// Sets the Command property.&#xD;
/// &amp;lt;/summary&amp;gt;&#xD;
public static void SetCommand(DependencyObject d, ICommand value)&#xD;
{&#xD;
    d.SetValue(CommandProperty, value);&#xD;
}&#xD;
&#xD;
/// &amp;lt;summary&amp;gt;&#xD;
/// Handles changes to the Command property.&#xD;
/// &amp;lt;/summary&amp;gt;&#xD;
private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)&#xD;
{&#xD;
    if (d is Button)&#xD;
    {&#xD;
        Button b = d as Button;&#xD;
        ICommand c = e.NewValue as ICommand;&#xD;
        b.Click += delegate(object sender, RoutedEventArgs arg) { c.Execute(null); };&#xD;
    }&#xD;
}&#xD;
&#xD;
#endregion&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
In the View Model, then, is the actual handler for the command&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp"&gt;public class PageViewModel&#xD;
{&#xD;
    public ICommand SayHello&#xD;
    {&#xD;
        get&#xD;
        {&#xD;
            return new RelayCommand(param =&amp;gt; MessageBox.Show("HelloWorld"));&#xD;
        }&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
Note that I’m using Josh’s RelayCommand helper to wrap the simple lambda.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
That feels like not too terribly much infrastructure, although I might have to create&#xD;
separate attached properties to handle different control types (e.g. those that don’t&#xD;
have a Click event).  It would be pretty straightforward to support command parameters&#xD;
in the same way, by creating a CommandParameter attached property and picking up its&#xD;
value in the OnCommandChanged handler…&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="brush: csharp"&gt;private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)&#xD;
{&#xD;
    if (d is Button)&#xD;
    {&#xD;
        string parameter = d.GetValue(CommandParameterProperty) as string;&#xD;
        Button b = d as Button;&#xD;
        ICommand c = e.NewValue as ICommand;&#xD;
        b.Click += delegate(object sender, RoutedEventArgs arg) { c.Execute(parameter); };&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
The only thing that doesn’t really handle well is the CanExecute method, which in&#xD;
WPF would automatically enable/disable the button based on the result of the ICommand’s&#xD;
CanExecute method.  I tried a couple ways of wiring it up during the OnCommandChanged&#xD;
handler, but couldn’t come up with anything that didn’t look to have nasty side-effect&#xD;
(garbage collection, etc.) or be just ugly.  I’d probably just bind the IsEnable&#xD;
property of the button to a separate boolean on the View Model and deal with it there.  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;strong&gt;Update:&lt;/strong&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Code is &lt;a href="http://www.cauldwell.net/patrick/work/SilverlightCommands.zip"&gt;here&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b2wl5XB4SBc:KS8p4KYuhmc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b2wl5XB4SBc:KS8p4KYuhmc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b2wl5XB4SBc:KS8p4KYuhmc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b2wl5XB4SBc:KS8p4KYuhmc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b2wl5XB4SBc:KS8p4KYuhmc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=b2wl5XB4SBc:KS8p4KYuhmc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b2wl5XB4SBc:KS8p4KYuhmc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=b2wl5XB4SBc:KS8p4KYuhmc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=b2wl5XB4SBc:KS8p4KYuhmc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,b1aa6fe5-fa05-4171-b565-25a4062e31f6.aspx</comments>
      <category>Design Patterns</category>
      <category>Silverlight</category>
      <category>Work</category>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/MVVMBindingToCommandsInSilverlight.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.cauldwell.net/patrick/blog/Trackback.aspx?guid=2c0a4bfd-69ca-4e3a-8e6f-96abb31f954b</trackback:ping>
      <pingback:server>http://www.cauldwell.net/patrick/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.cauldwell.net/patrick/blog/PermaLink,guid,2c0a4bfd-69ca-4e3a-8e6f-96abb31f954b.aspx</pingback:target>
      <dc:creator>Patrick Cauldwell</dc:creator>
      <wfw:comment>http://www.cauldwell.net/patrick/blog/CommentView,guid,2c0a4bfd-69ca-4e3a-8e6f-96abb31f954b.aspx</wfw:comment>
      <wfw:commentRss>http://www.cauldwell.net/patrick/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2c0a4bfd-69ca-4e3a-8e6f-96abb31f954b</wfw:commentRss>
      
      <title>Replacing JavaScript with Silverlight</title>
      <guid isPermaLink="false">http://www.cauldwell.net/patrick/blog/PermaLink,guid,2c0a4bfd-69ca-4e3a-8e6f-96abb31f954b.aspx</guid>
      <link>http://feedproxy.google.com/~r/PatrickCauldwellsBlog/~3/dcQwK8VIbZo/ReplacingJavaScriptWithSilverlight.aspx</link>
      <pubDate>Mon, 02 Mar 2009 23:08:15 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://blogs.sftsrc.com/shaun"&gt;Shaun&lt;/a&gt; posted a nice concise &lt;a href="http://blogs.sftsrc.com/shaun/archive/2009/02/23.aspx"&gt;example&lt;/a&gt; of&#xD;
replacing JavaScript code with similar compiled code in Silverlight.  If you&#xD;
have any complex business logic currently written in JavaScript, this would be a great&#xD;
way of turning that into compiled, type-safe C#.&#xD;
&lt;/p&gt;&#xD;
        &lt;br&gt;&#xD;
        &lt;hr&gt;&lt;/hr&gt;&#xD;
The posts on this weblog are provided AS IS with no warranties, and confer no rights.&#xD;
The opinions expressed herein are my own personal opinions and do not represent my&#xD;
employer's view in any way.&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=dcQwK8VIbZo:-4J9jhFIExk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=dcQwK8VIbZo:-4J9jhFIExk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=dcQwK8VIbZo:-4J9jhFIExk:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=dcQwK8VIbZo:-4J9jhFIExk:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=dcQwK8VIbZo:-4J9jhFIExk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=dcQwK8VIbZo:-4J9jhFIExk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=dcQwK8VIbZo:-4J9jhFIExk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?i=dcQwK8VIbZo:-4J9jhFIExk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?a=dcQwK8VIbZo:-4J9jhFIExk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PatrickCauldwellsBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <comments>http://www.cauldwell.net/patrick/blog/CommentView,guid,2c0a4bfd-69ca-4e3a-8e6f-96abb31f954b.aspx</comments>
    <feedburner:origLink>http://www.cauldwell.net/patrick/blog/ReplacingJavaScriptWithSilverlight.aspx</feedburner:origLink></item>
  </channel>
</rss>
