<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Michael Maddox - Software Development</title>
  <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/" />
  <link rel="self" href="http://www.capprime.com/software_development_weblog/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2011-01-21T07:58:14.6103111-07:00</updated>
  <author>
    <name>Michael Maddox</name>
  </author>
  <subtitle>Best Practices, Knowlegde Base Type Articles, General Tech Opinions, etc.</subtitle>
  <id>http://www.capprime.com/software_development_weblog/</id>
  <generator uri="http://dasblog.info/" version="2.3.9074.18820">DasBlog</generator>
  <entry>
    <title>The State of DVCS January 2011</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2011/01/21/TheStateOfDVCSJanuary2011.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,4c082350-7d33-41ad-9d0b-450e6971017c.aspx</id>
    <published>2011-01-21T07:58:14.6103111-07:00</published>
    <updated>2011-01-21T07:58:14.6103111-07:00</updated>
    <category term="DVCS" label="DVCS" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,DVCS.aspx" />
    <category term="Knowledge Base" label="Knowledge Base" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,KnowledgeBase.aspx" />
    <category term="SourceGear Veracity" label="SourceGear Veracity" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,SourceGearVeracity.aspx" />
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
This blog post is a repurposing of content I created for a presentation I gave on
DVCS on 01-11-2011 to the <a href="http://www.twincitiesdevelopersgroup.com/2010/11/11/jan-11/">Twin
Cities Developer Group</a>.
</p>
        <p>
...
</p>
        <p>
What is DVCS?
</p>
        <p>
Source code version control without a central master server repository (think peer
to peer).
</p>
        <p>
Market leaders: <a href="http://git-scm.com/">git</a>, <a href="http://mercurial.selenic.com/">hg
/ Mercurial</a></p>
        <p>
New competitor with potential: <a href="http://www.sourcegear.com/veracity/">SourceGear
Veracity</a></p>
        <p>
          <a href="http://en.wikipedia.org/wiki/Distributed_revision_control">http://en.wikipedia.org/wiki/Distributed_revision_control</a>
        </p>
        <p>
...
</p>
        <p>
Is DVCS better than non-distributed source control (aka Subversion/SVN, VSS, TFS,
etc.)?
</p>
        <p>
Usually, yes, but there are exceptions.  Don't underestimate the learning curve.
</p>
        <p>
          <a href="http://stackoverflow.com/questions/111031/comparison-between-centralized-and-distributed-version-control-systems">http://stackoverflow.com/questions/111031/comparison-between-centralized-and-distributed-version-control-systems</a>
        </p>
        <p>
...
</p>
        <p>
What are the Disadvantages of DVCS?
</p>
        <p>
Lack of mature graphical front ends (although people seem okay with TortoiseHg/TortoiseGit),
the majority of DVCS users appear to use the command line.
</p>
        <p>
The learning curve for DVCS is different.
</p>
        <p>
There are different complexities like workflow &amp; backup process creation.
</p>
        <p>
Many people struggle with the concept of "no canonical master".
</p>
        <p>
Large binary files don't work well in a DVCS where everyone has a local copy of basically
the entirety of every version of every binary file.
</p>
        <p>
There are currently tools to migrate to DVCS, but not necessarily tools to migrate
away from DVCS.
</p>
        <p>
...
</p>
        <p>
Advantages of DVCS – Better Implementation
</p>
        <p>
What could non-distributed version controls systems do better to compete with DVCS?
</p>
        <ul dir="ltr" style="MARGIN-RIGHT: 0px">
          <li>
Implement better merging</li>
          <li>
Implement better handling of versioning directories</li>
        </ul>
        <p>
What are some of the reasons that merging is better in DVCS?
</p>
        <ul>
          <li>
Change sets</li>
          <li>
Likely more version history available to work with since smaller check-ins are better
supported</li>
          <li>
Better ancestor tracking/usage</li>
          <li>
Better directory revision management</li>
          <li>
Better file rename detection</li>
        </ul>
        <p>
The battle is not DVCS (git/hg) vs. SVN, but that is how it is often characterized. 
SVN is lacking in some areas compared to it's (sometimes commercial, sometimes more
mature) non-distributed version control competitors.
</p>
        <p>
...
</p>
        <p>
Advantages of DVCS – Better Design
</p>
        <p>
What can’t non-distributed version controls systems do?
</p>
        <ul>
          <li>
Working "offline" (faster history access, faster commits)</li>
          <li>
Better experience working peer to peer for integration testing</li>
          <li>
QA can manage their own repository</li>
          <li>
Can commit a logical unit of work without tests passing or the code even compiling</li>
        </ul>
        <p>
...
</p>
        <p>
DVCS Trends
</p>
        <p>
Where is DVCS catching up?
</p>
        <ul>
          <li>
GUIs</li>
          <li>
            <a href="http://en.wikipedia.org/wiki/Application_lifecycle_management">ALM</a> integration</li>
          <li>
Hard locks</li>
          <li>
User/role permissions</li>
          <li>
Centralized admin, etc.</li>
        </ul>
        <p>
DVCS in corporations is very interesting to me personally and Veracity will likely
solve those problems better than git/hg ever will since they are primarily targeted
at open source projects, not corporate/enterprise environments.
</p>
        <p>
Obstacles to an enterprise DVCS - <a href="http://www.ericsink.com/articles/vcs_trends.html">http://www.ericsink.com/articles/vcs_trends.html</a></p>
        <p>
...
</p>
        <p>
Some differences between Mercurial and Veracity
</p>
        <p>
          <a href="http://www.capprime.com/software_development_weblog/2011/01/20/SourceGearVeracityMercurialLookupChart.aspx">http://www.capprime.com/software_development_weblog/2011/01/20/SourceGearVeracityMercurialLookupChart.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=4c082350-7d33-41ad-9d0b-450e6971017c" />
      </div>
    </content>
  </entry>
  <entry>
    <title>SourceGear Veracity / Mercurial Lookup Chart</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2011/01/20/SourceGearVeracityMercurialLookupChart.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,7e22f5fb-2271-4b07-91d7-2ca6a1c2ce3b.aspx</id>
    <published>2011-01-20T11:11:41.1296697-07:00</published>
    <updated>2011-01-20T11:11:41.1296697-07:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,KnowledgeBase.aspx" />
    <category term="Tools" label="Tools" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,Tools.aspx" />
    <category term="SourceGear Veracity" label="SourceGear Veracity" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,SourceGearVeracity.aspx" />
    <category term="DVCS" label="DVCS" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,DVCS.aspx" />
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Please note: The following information is specific to the 01-19-2011 Veracity nightly
build (version 0.5.5.10370).  I may come back from time to time as the Veracity
command API solidifies to update this to newer and more accurate information.
</p>
        <p>
          <br />
SourceGear Veracity tends to be more like Mercurial / hg than like git.  There
is a ton of documentation on Mercurial, but not much available for Veracity at the
moment.
</p>
        <p>
While learning Veracity, I often found myself reading docs for Mercurial and then
figuring out how Veracity was different through trial and error.
</p>
        <p>
This blog posts contains my notes on some of the things I've learned.
</p>
        <p>
It's often possible to replace an hg command one for one with a vv command (i.e. hg
status ~= vv status) and the results will be meaningfully similar if not exactly the
same.
</p>
        <p>
...
</p>
        <p>
Generally, step one is to create your repo.  In Mercurial, this is done by creating
a new directory and executing "hg init" within that directory.  For Veracity,
you do the same basic thing, but you also need to give the repo a name as a parameter
to init:
</p>
        <p>
vv init repo1
</p>
        <p>
After initializing a repository, the first logical step is to setup your user. 
In Mercurial, this is done by creating an .hgrc file in the appropriate location. 
In Veracity, you must first create the user if they don't yet exist (use "vv users"
to show existing users) using:
</p>
        <p>
vv createuser <a href="mailto:myemail@example.com">myemail@example.com</a></p>
        <p>
Once the user exists, you set the current user using:
</p>
        <p>
vv whoami <a href="mailto:myemail@example.com">myemail@example.com</a></p>
        <p>
You can use "vv whoami" at any time to see who Veracity thinks you currently are.
</p>
        <p>
...
</p>
        <p>
Once you have a repository, you can startup a web server to view the repository (although
there obviously won't be much to look at if you just initialized it).  For Mercurial,
this is simply:
</p>
        <p>
hg serve
</p>
        <p>
For Veracity, the "vv serve" command requires you first run "vv localsettings set
server/files &lt;path&gt;" to provide a path to the website files.  I suspect
Mercurial does not need this "set server files" step because the installer takes care
of setting this path somehow.
</p>
        <p>
...
</p>
        <p>
The status command works the same, but the output is visibly different (git's output
is visibly different for the status command as well).
</p>
        <p>
...
</p>
        <p>
The add command requires a file or directory name in Veracity, whereas Mercurial will
add all files if you don't specify a parameter.
</p>
        <p>
Like Mercurial (and unlike git), you only need to use the add command on new files
(modified existing files are automatically part of the change set by default).
</p>
        <p>
...
</p>
        <p>
The commit command works similarly, although hg has a nice feature where it will pop
up an editor to provide a commit comment while Veracity works more like git in that
you provide the commit message with a command line parameter (which is also possible
with hg).
</p>
        <p>
...
</p>
        <p>
A basic no parameter diff works very similarly between Veracity and Mercurial.
</p>
        <p>
...
</p>
        <p>
The branch and branches commands with no parameters work exactly the same.
</p>
        <p>
Creating a new branch in Veracity requires adding a "--new" parameter (Mercurial doesn't
need/use "--new"):
</p>
        <p>
vv branch branch_name_here --new
</p>
        <p>
One interesting branching difference is that the default branch in Mercurial is named
"default", but in Veracity (as well as git), the default branch is named "master".
</p>
        <p>
...
</p>
        <p>
To switch branches in Veracity, you use the branch or update (with -b parameter before
the branch name) command.
</p>
        <p>
vv update -b master -aka- vv branch master<br />
vv update -b branch1 -aka- vv branch branch1 
</p>
        <p>
To switch branches in hg, you use the update or checkout command.
</p>
        <p>
hg update default<br />
hg update branch1
</p>
        <p>
(To switch branches in git, you use the checkout command.)
</p>
        <p>
...
</p>
        <p>
Cloning a repository from a web server is different.
</p>
        <p>
hg:
</p>
        <p>
hg clone <a href="http://localhost:8000/">http://localhost:8000/</a> .
</p>
        <p>
Veracity:
</p>
        <p>
vv clone <a href="http://localhost:8080/repos/corprepo">http://localhost:8080/repos/corprepo</a> localdevrepo<br />
vv checkout localdevrepo
</p>
        <p>
...
</p>
        <p>
Pushing and pulling from a repository is basically the same in the no parameter scenario:
</p>
        <p>
&gt;hg pull<br />
pulling from <a href="http://localhost:8000/">http://localhost:8000/</a><br />
searching for changes<br />
no changes found
</p>
        <p>
&gt;hg push<br />
pushing to <a href="http://localhost:8000/">http://localhost:8000/</a><br />
searching for changes<br />
no changes found
</p>
        <p>
&gt;vv pull<br />
Pulling from <a href="http://localhost:8080/repos/corprepo">http://localhost:8080/repos/corprepo</a>:<br />
Retrieving dagnodes...done<br />
Retrieving blobs...done<br />
Committing changes...done<br />
Merging databases...done
</p>
        <p>
&gt;vv push<br />
Pushing to <a href="http://localhost:8080/repos/corprepo">http://localhost:8080/repos/corprepo</a>:<br />
Sending dagnodes...done<br />
Sending blobs...done<br />
Committing changes...done<br />
Cleaning up...done
</p>
        <p>
Veracity currently only supports pushing and pulling from a cloned repo to it's "parent",
but SourceGear is actively working on enhancements in this area.<br /></p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=7e22f5fb-2271-4b07-91d7-2ca6a1c2ce3b" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using the Google Checkout 2.5 API with ASP.NET MVC - The Missing Sample</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2010/11/29/UsingTheGoogleCheckout25APIWithASPNETMVCTheMissingSample.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,8ef1e00d-2b08-4c3a-ae74-18c698eb3d89.aspx</id>
    <published>2010-11-29T05:06:24.415-07:00</published>
    <updated>2010-11-29T05:22:21.2225216-07:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,KnowledgeBase.aspx" />
    <category term="Web Services" label="Web Services" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,WebServices.aspx" />
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
In May of 2010, Google released a new 2.5 version of the Google Checkout API. 
The most compelling feature of this version of the API is that it no longer requires
https/SSL to retrieve notifications.  They didn't update the .NET sample code
to show how to use the new API though (it's now November, so it's been six months).
</p>
        <p>
Below I have not only included the missing sample code for notification handling with
GCO 2.5, but I did it using ASP.NET MVC instead of ASP.NET Classic WebForms. 
I believe this is the first published Google Checkout ASP.NET MVC sample.
</p>
        <p>
You will want to check the Integration Console in the Google Checkout Sandbox website
constantly while testing.  Some errors will only show up there.  You will
also want to catch and log errors somewhere like a database, which the below sample
does not do.  You may also want to send yourself an e-mail when an order comes
through.  You'll have to code that feature yourself, it's not too difficult.
</p>
        <p>
          <br />
First, Download the <a href="http://code.google.com/p/google-checkout-dotnet-sample-code/downloads/list">Google
Checkout .NET DLLs</a> (at least version 2.5.0.3, published 10-16-2010)<br />
Unzip the Google Checkout .NET DLLs and put them somewhere you can find them later
</p>
        <p>
          <br />
Next, Start Visual Studio 2008
</p>
        <p>
File -&gt; New -&gt; Project<br />
 Visual C# -&gt; Web -&gt; ASP.NET MVC Web Application<br />
  GcoNotifHandlerForSandbox<br />
  OK<br />
 No, do not create a unit test project<br />
  OK
</p>
        <p>
In Solution Explorer -&gt; Right Click References -&gt; Add Reference...<br />
 Select the "GCheckout.dll" you downloaded and unzipped above<br />
 OK
</p>
        <p>
Open web.config for editing:<br />
 Replace "&lt;appSettings/&gt;" with:
</p>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
&lt;
</p>
          </font>
        </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">appSettings</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">&gt;<br />
  &lt;</font>
        </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">add</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
          </font>
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">key</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">=</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">GoogleMerchantID</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
          </font>
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">value</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">=</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">YourMerchantID</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2"> /&gt;<br />
  &lt;</font>
        </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">add</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
          </font>
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">key</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">=</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">GoogleMerchantKey</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
          </font>
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">value</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">=</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">YourMerchantKey</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2"> /&gt;<br />
  &lt;</font>
        </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">add</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
          </font>
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">key</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">=</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">GoogleEnvironment</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
          </font>
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">value</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">=</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">Sandbox</font>
        </font>
        <font color="#000000" size="2">"</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2"> /&gt;<br />
&lt;/</font>
        </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">appSettings</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">&gt;
<p></p></font>
        </font>Be sure to substitute in your proper sandbox merchant ID and key.
<p>
In Solution Explorer -&gt; Right Click Controllers -&gt; Add -&gt; Controller...<br />
 Controller Name: GcoNotifHandlerController<br />
 Add
</p><p>
Open Global.asax.cs for editing:<br />
 Add a new route before the default route:
</p><font size="2"><p>
routes.MapRoute(<br /></p></font><font color="#a31515" size="2"><font color="#a31515" size="2">  "GcoNotifHandler"</font></font><font size="2">,<br /></font><font color="#a31515" size="2"><font color="#a31515" size="2">  "{controller}/{action}/{id}"</font></font><font size="2">,<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  new</font></font><font size="2"> {
controller = </font><font color="#a31515" size="2"><font color="#a31515" size="2">"GcoNotifHandler"</font></font><font size="2">,
action = </font><font color="#a31515" size="2"><font color="#a31515" size="2">"Index"</font></font><font size="2">,
id = </font><font color="#a31515" size="2"><font color="#a31515" size="2">""</font></font><font size="2"> }<br />
);
<p></p></font>In Solution Explorer -&gt; Right Click Models -&gt; Add -&gt; Class...<br />
 Name: GoogleCheckoutHelper.cs<br />
 Add
<p>
Add the following new static methods to GoogleCheckoutHelper:
</p><font size="2"><p></p></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">public</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">static</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">string</font></font><font size="2"> GetGoogleOrderNumber(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">string</font></font><font size="2"> serialNumber)<br />
{<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  return</font></font><font size="2"> serialNumber.Substring(0,
serialNumber.IndexOf(</font><font color="#a31515" size="2"><font color="#a31515" size="2">'-'</font></font><font size="2">));<br />
}
<p></p></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">private</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">static</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">void</font></font><font size="2"> HandleAuthorizationAmountNotification(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">AuthorizationAmountNotification </font></font><font size="2">inputAuthorizationAmountNotification)<br />
{<br /></font><font color="#008000" size="2"><font color="#008000" size="2">  // TODO:
Add custom processing for this notification type<br /></font></font><font size="2">}
<p></p></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">private</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">static</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">void</font></font><font size="2"> HandleChargeAmountNotification(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ChargeAmountNotification</font></font><font size="2"> inputChargeAmountNotification)<br />
{<br /></font><font color="#008000" size="2"><font color="#008000" size="2">  // TODO:
Add custom processing for this notification type<br /></font></font><font size="2">}
<p></p></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">private</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">static</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">void</font></font><font size="2"> HandleNewOrderNotification(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">NewOrderNotification</font></font><font size="2"> inputNewOrderNotification)<br />
{<br /></font><font color="#008000" size="2"><font color="#008000" size="2">  // Retrieve
data from MerchantPrivateData<br /></font></font><font size="2">  GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">anyMultiple</font></font><font size="2"> oneAnyMultiple
= inputNewOrderNotification.shoppingcart.merchantprivatedata;<br />
  System.Xml.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">XmlNode</font></font><font size="2">[]
oneXmlNodeArray = oneAnyMultiple.Any;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  string</font></font><font size="2"> hiddenMerchantPrivateData
= oneXmlNodeArray[0].InnerText;<br /></font><font color="#008000" size="2"><font color="#008000" size="2">  // TODO:
Process the MerchantPrivateData if provided</font></font><p><font color="#0000ff" size="2"><font color="#0000ff" size="2">  foreach</font></font><font size="2"> (GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Item</font></font><font size="2"> oneItem </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">in</font></font><font size="2"> inputNewOrderNotification.shoppingcart.items)<br />
  {<br /></font><font color="#008000" size="2"><font color="#008000" size="2">   
// TODO: Get MerchantItemId from shopping cart item (oneItem.merchantitemid) and process
it<br /></font></font><font size="2">  }</font></p><p><font color="#008000" size="2"><font color="#008000" size="2">  // TODO: Add
custom processing for this notification type<br /></font></font><font size="2">}
</font></p><p><font color="#0000ff" size="2"><font color="#0000ff" size="2">private</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">static</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">void</font></font><font size="2"> HandleOrderStateChangeNotification(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">OrderStateChangeNotification</font></font><font size="2"> inputOrderStateChangeNotification)<br />
{<br /></font><font color="#008000" size="2"><font color="#008000" size="2">  // Charge
Order If Chargeable<br /></font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"> 
if</font></font><font size="2"> ((inputOrderStateChangeNotification.previousfinancialorderstate.ToString().Equals(</font><font color="#a31515" size="2"><font color="#a31515" size="2">"REVIEWING"</font></font><font size="2">))
&amp;&amp; (inputOrderStateChangeNotification.newfinancialorderstate.ToString().Equals(</font><font color="#a31515" size="2"><font color="#a31515" size="2">"CHARGEABLE"</font></font><font size="2">)))<br />
  {<br />
    GCheckout.OrderProcessing.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ChargeOrderRequest</font></font><font size="2"> oneChargeOrderRequest
= </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"> GCheckout.OrderProcessing.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ChargeOrderRequest</font></font><font size="2">(inputOrderStateChangeNotification.googleordernumber);<br />
    GCheckout.Util.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">GCheckoutResponse</font></font><font size="2"> oneGCheckoutResponse
= oneChargeOrderRequest.Send();<br />
  }
</font></p><p><font color="#008000" size="2"><font color="#008000" size="2">  // Update License
If Charged<br /></font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"> 
if</font></font><font size="2"> ((inputOrderStateChangeNotification.previousfinancialorderstate.ToString().Equals(</font><font color="#a31515" size="2"><font color="#a31515" size="2">"CHARGING"</font></font><font size="2">))
&amp;&amp; (inputOrderStateChangeNotification.newfinancialorderstate.ToString().Equals(</font><font color="#a31515" size="2"><font color="#a31515" size="2">"CHARGED"</font></font><font size="2">)))<br />
  {<br /></font><font color="#008000" size="2"><font color="#008000" size="2">   
// TODO: For each shopping cart item received in the NewOrderNotification, authorize
the license<br /></font></font><font size="2">  }</font></p><p><font color="#008000" size="2"><font color="#008000" size="2">  // TODO: Add
custom processing for this notification type<br /></font></font><font size="2">}
</font></p><p><font color="#0000ff" size="2"><font color="#0000ff" size="2">private</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">static</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">void</font></font><font size="2"> HandleRiskInformationNotification(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">RiskInformationNotification</font></font><font size="2"> inputRiskInformationNotification)<br />
{<br /></font><font color="#008000" size="2"><font color="#008000" size="2">  // TODO:
Add custom processing for this notification type<br /></font></font><font size="2">}
</font></p><p><font color="#0000ff" size="2"><font color="#0000ff" size="2">public</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">static</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">void</font></font><font size="2"> ProcessNotification(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">string</font></font><font size="2"> serialNumber)<br />
{<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  string</font></font><font size="2"> googleOrderNumber
= GetGoogleOrderNumber(serialNumber);</font></p><p><font color="#2b91af" size="2"><font color="#2b91af" size="2">  List</font></font><font size="2">&lt;</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">string</font></font><font size="2">&gt;
listOfGoogleOrderNumbers = </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"></font><font color="#2b91af" size="2"><font color="#2b91af" size="2">List</font></font><font size="2">&lt;</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">string</font></font><font size="2">&gt;
{ googleOrderNumber };</font></p><p><font size="2">  GCheckout.OrderProcessing.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">NotificationHistoryRequest</font></font><font size="2"> oneNotificationHistoryRequest
= </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"> GCheckout.OrderProcessing.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">NotificationHistoryRequest</font></font><font size="2">(listOfGoogleOrderNumbers);</font></p><p><font size="2">  GCheckout.OrderProcessing.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">NotificationHistoryResponse</font></font><font size="2"> oneNotificationHistoryResponse
= (GCheckout.OrderProcessing.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">NotificationHistoryResponse</font></font><font size="2">)oneNotificationHistoryRequest.Send();</font></p><p><font color="#008000" size="2"><font color="#008000" size="2">  // oneNotificationHistoryResponse.ResponseXml
contains the complete response</font></font></p><p><font color="#008000" size="2"><font color="#008000" size="2">  // Iterate through
the notification history for this order looking for the notification that exactly
matches the given serial number<br /></font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"> 
foreach</font></font><font size="2"> (</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">object</font></font><font size="2"> oneNotification </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">in</font></font><font size="2"> oneNotificationHistoryResponse.NotificationResponses)<br />
  {<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">   
if</font></font><font size="2"> (oneNotification.GetType().Equals(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">typeof</font></font><font size="2">(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">NewOrderNotification</font></font><font size="2">)))<br />
    {<br />
      GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">NewOrderNotification</font></font><font size="2"> oneNewOrderNotification
= (GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">NewOrderNotification</font></font><font size="2">)oneNotification;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">     
if</font></font><font size="2"> (oneNewOrderNotification.serialnumber.Equals(serialNumber))<br />
      {<br />
        HandleNewOrderNotification(oneNewOrderNotification);<br />
      }<br />
    }<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">   
else</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">if</font></font><font size="2"> (oneNotification.GetType().Equals(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">typeof</font></font><font size="2">(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">OrderStateChangeNotification</font></font><font size="2">)))<br />
    {<br />
      GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">OrderStateChangeNotification</font></font><font size="2"> oneOrderStateChangeNotification
= (GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">OrderStateChangeNotification</font></font><font size="2">)oneNotification;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">     
if</font></font><font size="2"> (oneOrderStateChangeNotification.serialnumber.Equals(serialNumber))<br />
      {<br />
        HandleOrderStateChangeNotification(oneOrderStateChangeNotification);<br />
      }<br />
    }<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">   
else</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">if</font></font><font size="2"> (oneNotification.GetType().Equals(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">typeof</font></font><font size="2">(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">RiskInformationNotification</font></font><font size="2">)))<br />
    {<br />
      GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">RiskInformationNotification</font></font><font size="2"> oneRiskInformationNotification
= (GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">RiskInformationNotification</font></font><font size="2">)oneNotification;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">     
if</font></font><font size="2"> (oneRiskInformationNotification.serialnumber.Equals(serialNumber))<br />
      {<br />
        HandleRiskInformationNotification(oneRiskInformationNotification);<br />
      }<br />
    }<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">   
else</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">if</font></font><font size="2"> (oneNotification.GetType().Equals(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">typeof</font></font><font size="2">(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">AuthorizationAmountNotification</font></font><font size="2">)))<br />
    {<br />
      GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">AuthorizationAmountNotification</font></font><font size="2"> oneAuthorizationAmountNotification
= (GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">AuthorizationAmountNotification</font></font><font size="2">)oneNotification;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">     
if</font></font><font size="2"> (oneAuthorizationAmountNotification.serialnumber.Equals(serialNumber))<br />
      {<br />
        HandleAuthorizationAmountNotification(oneAuthorizationAmountNotification);<br />
      }<br />
    }<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">   
else</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">if</font></font><font size="2"> (oneNotification.GetType().Equals(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">typeof</font></font><font size="2">(GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ChargeAmountNotification</font></font><font size="2">)))<br />
    {<br />
      GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ChargeAmountNotification</font></font><font size="2"> oneChargeAmountNotification
= (GCheckout.AutoGen.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ChargeAmountNotification</font></font><font size="2">)oneNotification;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">     
if</font></font><font size="2"> (oneChargeAmountNotification.serialnumber.Equals(serialNumber))<br />
      {<br />
        HandleChargeAmountNotification(oneChargeAmountNotification);<br /></font><font size="2">      }<br />
    }<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">   
else<br /></font></font><font size="2">    {<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">     
throw</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"></font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ArgumentOutOfRangeException</font></font><font size="2">(</font><font color="#a31515" size="2"><font color="#a31515" size="2">"Unhandled
Type ["</font></font><font size="2"> + oneNotification.GetType().ToString() + </font><font color="#a31515" size="2"><font color="#a31515" size="2">"]!;
serialNumber=["</font></font><font size="2"> + serialNumber + </font><font color="#a31515" size="2"><font color="#a31515" size="2">"];"</font></font><font size="2">);<br />
    }<br />
  }<br />
}
</font></p><p><br />
Open Controllers\GcoNotifHandlerController.cs for editing:<br />
 Replace the Index method with:
</p><font size="2"><p></p></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">public</font></font><font size="2"></font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ActionResult</font></font><font size="2"> Index()<br />
{<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  string</font></font><font size="2"> serialNumber
= </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">null</font></font><font size="2">;
<p></p></font><font color="#008000" size="2"><font color="#008000" size="2">  //
Receive Request<br /></font></font><font size="2">  System.IO.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Stream</font></font><font size="2"> requestInputStream
= Request.InputStream;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  string</font></font><font size="2"> requestStreamAsString
= </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">null</font></font><font size="2">;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  using</font></font><font size="2"> (System.IO.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">StreamReader</font></font><font size="2"> oneStreamReader
= </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"> System.IO.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">StreamReader</font></font><font size="2">(requestInputStream))<br />
  {<br />
    requestStreamAsString = oneStreamReader.ReadToEnd();<br />
  }
<p></p></font><font color="#008000" size="2"><font color="#008000" size="2">  //
Parse Request to retreive serial number<br /></font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"> 
string</font></font><font size="2">[] requestStreamAsParts = requestStreamAsString.Split(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">char</font></font><font size="2">[]
{ </font><font color="#a31515" size="2"><font color="#a31515" size="2">'='</font></font><font size="2"> });<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  if</font></font><font size="2"> (requestStreamAsParts.Length
&gt;= 2)<br />
  {<br />
    serialNumber = requestStreamAsParts[1];<br />
  }
<p></p></font><font color="#008000" size="2"><font color="#008000" size="2">  //
Call NotificationHistory Google Checkout API to retrieve the notification for the
given serial number and process the notification<br /></font></font><font size="2">  GcoNotifHandlerForSandbox.Models.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">GoogleCheckoutHelper</font></font><font size="2">.ProcessNotification(serialNumber);
<p></p></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  string</font></font><font size="2"> notifAckBegin
= </font><font color="#a31515" size="2"><font color="#a31515" size="2">"&lt;notification-acknowledgment
xmlns=\"http://checkout.google.com/schema/2\""</font></font><font size="2">;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  string</font></font><font size="2"> notifAckSerialNumAttrBegin
= </font><font color="#a31515" size="2"><font color="#a31515" size="2">" serial-number=\""</font></font><font size="2">;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  string</font></font><font size="2"> notifAckSerialNumAttrEnd
= </font><font color="#a31515" size="2"><font color="#a31515" size="2">"\""</font></font><font size="2">;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  string</font></font><font size="2"> notifAckEnd
= </font><font color="#a31515" size="2"><font color="#a31515" size="2">" /&gt;"</font></font><font size="2">;<br /></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">  return</font></font><font size="2"></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">this</font></font><font size="2">.Content(notifAckBegin
+ notifAckSerialNumAttrBegin + serialNumber + notifAckSerialNumAttrEnd + notifAckEnd);<br />
}
</font><p><br />
That's all there is for building the basic notification handling web service.
</p><p>
You need to publish your notification handling web service to a public website and
configure your Google Checkout sandbox account (at <a href="https://sandbox.google.com/checkout/sell/">https://sandbox.google.com/checkout/sell/</a> -&gt;
Settings -&gt; Integration -&gt; API Callback URL) to use the URL of your web service
(http://www.&lt;yourdomain&gt;.com/GcoNotifHandlerForSandbox/).
</p><p>
The Callback contents should be set to "Notification Serial Number" and the API Version
should be set to "Version 2.5".
</p><p><br />
To test your notification web service, you'll need a website with a Google Checkout
button.  Instructions for building that are available here:
</p><p><a href="http://code.google.com/apis/checkout/samples/Google_Checkout_Sample_Code_NET.html">http://code.google.com/apis/checkout/samples/Google_Checkout_Sample_Code_NET.html</a></p><p><br />
(Note: I have successfully tested this with both ASP.NET MVC 1 &amp; 2 for Visual
Studio 2008.)
</p><p><br />
Good luck!
</p><img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=8ef1e00d-2b08-4c3a-ae74-18c698eb3d89" /></div>
    </content>
  </entry>
  <entry>
    <title>Consuming OData from Silverlight 4 with Visual Studio 2010</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2010/08/07/ConsumingODataFromSilverlight4WithVisualStudio2010.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,4839bf08-5a1b-4b2a-954d-aa90d0f3f979.aspx</id>
    <published>2010-08-07T04:49:17.0026919-07:00</published>
    <updated>2010-08-07T04:49:17.0026919-07:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,KnowledgeBase.aspx" />
    <category term="Visual Studio 2010" label="Visual Studio 2010" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,VisualStudio2010.aspx" />
    <category term="Web Services" label="Web Services" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,WebServices.aspx" />
    <category term="Silverlight" label="Silverlight" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,Silverlight.aspx" />
    <category term="OData" label="OData" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,OData.aspx" />
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Consuming OData from Silverlight 4 can be a very frustrating experience for people
like me who are just now joining the Silverlight party.
</p>
        <p>
When it doesn't work, it can fail silently and/or with incorrectly worded warnings.
</p>
        <p>
This is a perfect example of where a blog post can hopefully fill in some of the gaps
left by the Microsoft documentation.
</p>
        <p>
First, let's setup a very simple Silverlight 4 application against the odata.org Northwind
service.
</p>
        <p>
Note: You may need to install the Silverlight 4 Tools for VS 2010 for this sample.<br />
 <a href="http://www.bing.com/search?q=Microsoft+Silverlight+4+Tools+for+Visual+Studio+2010">http://www.bing.com/search?q=Microsoft+Silverlight+4+Tools+for+Visual+Studio+2010</a></p>
        <p>
In Visual Studio 2010:
</p>
        <p>
File -&gt; New -&gt; Project<br />
 Visual C# -&gt; Silverlight -&gt; Silverlight Application -&gt; OK<br />
  New Silverlight Application wizard<br />
   Uncheck "Host the Silverlight application in a new website"<br />
   Silverlight Version: Silverlight 4<br />
   OK
</p>
        <p>
Right Click References in Solution Explorer -&gt; Add Service Reference...<br />
 Address: <a href="http://services.odata.org/Northwind/Northwind.svc/">http://services.odata.org/Northwind/Northwind.svc/</a><br />
 Namespace: RemoteNorthwindServiceReference<br />
 OK
</p>
        <p>
From the toolbox, drag and drop a DataGrid from the "Common Silverlight Controls"
section onto MainPage.xaml<br />
 Change the AutoGenerateColumns property to True<br />
 Change the Margin to 0,0,0,0<br />
 Change the Width to 400
</p>
        <p>
In MainPage.xaml.cs:<br />
 Add the following using statement:
</p>
        <p>
  <font face="Consolas" color="#0000ff" size="2"><font face="Consolas" color="#0000ff" size="2"><font face="Consolas" color="#0000ff" size="2">using</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"><font color="#000000"> System.Data.Services.Client;</font></font></font></p>
        <p>
 Add the following class variable:
</p>
        <p>
  <font face="Consolas" color="#0000ff" size="2"><font face="Consolas" color="#0000ff" size="2"><font face="Consolas" color="#0000ff" size="2">private</font></font></font><font face="Consolas" size="2"><font face="Consolas" color="#000000" size="2"></font></font><font face="Consolas" color="#2b91af" size="2"><font face="Consolas" color="#2b91af" size="2"><font face="Consolas" color="#2b91af" size="2">DataServiceCollection</font></font></font><font face="Consolas" size="2"><font face="Consolas" color="#000000" size="2">&lt;RemoteNorthwindServiceReference.</font></font><font face="Consolas" color="#2b91af" size="2"><font face="Consolas" color="#2b91af" size="2"><font face="Consolas" color="#2b91af" size="2">Shipper</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"><font color="#000000">&gt;
_shippers;</font></font></font></p>
        <p>
 Add the following to the bottom of the MainPage constructor method:
</p>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">
            <p>
  RemoteNorthwindServiceReference.
</p>
          </font>
        </font>
        <font face="Consolas" color="#2b91af" size="2">
          <font face="Consolas" color="#2b91af" size="2">
            <font face="Consolas" color="#2b91af" size="2">NorthwindEntities</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> remoteNorthwindService
=<br /></font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">   
new</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> RemoteNorthwindServiceReference.</font>
        </font>
        <font face="Consolas" color="#2b91af" size="2">
          <font face="Consolas" color="#2b91af" size="2">
            <font face="Consolas" color="#2b91af" size="2">NorthwindEntities</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">(<br /></font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">     
new</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">
          </font>
        </font>
        <font face="Consolas" color="#2b91af" size="2">
          <font face="Consolas" color="#2b91af" size="2">
            <font face="Consolas" color="#2b91af" size="2">Uri</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">(</font>
        </font>
        <font face="Consolas" color="#a31515" size="2">
          <font face="Consolas" color="#a31515" size="2">
            <font face="Consolas" color="#a31515" size="2">"http://services.odata.org/Northwind/Northwind.svc/"</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">));
<p>
  _shippers = 
</p></font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">new</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">
          </font>
        </font>
        <font face="Consolas" color="#2b91af" size="2">
          <font face="Consolas" color="#2b91af" size="2">
            <font face="Consolas" color="#2b91af" size="2">DataServiceCollection</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">&lt;RemoteNorthwindServiceReference.</font>
        </font>
        <font face="Consolas" color="#2b91af" size="2">
          <font face="Consolas" color="#2b91af" size="2">
            <font face="Consolas" color="#2b91af" size="2">Shipper</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">&gt;();<br />
  _shippers.LoadCompleted += </font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">new</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">
          </font>
        </font>
        <font face="Consolas" color="#2b91af" size="2">
          <font face="Consolas" color="#2b91af" size="2">
            <font face="Consolas" color="#2b91af" size="2">EventHandler</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">&lt;</font>
        </font>
        <font face="Consolas" color="#2b91af" size="2">
          <font face="Consolas" color="#2b91af" size="2">
            <font face="Consolas" color="#2b91af" size="2">LoadCompletedEventArgs</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">&gt;(_shippers_LoadCompleted);
<p></p></font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2"> 
var</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> query
= </font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">from</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> shippers </font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">in</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> remoteNorthwindService.Shippers </font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">select</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> shippers;<br />
  _shippers.LoadAsync(query);
</font>
        </font>
        <p>
 Add the following new method:
</p>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">
            <p>
            </p>
          </font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2"> 
private</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">
          </font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">void</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> _shippers_LoadCompleted(</font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">object</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> sender, </font>
        </font>
        <font face="Consolas" color="#2b91af" size="2">
          <font face="Consolas" color="#2b91af" size="2">
            <font face="Consolas" color="#2b91af" size="2">LoadCompletedEventArgs</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> e)<br />
  {<br /></font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">   
if</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2"> (_shippers.Continuation
!= </font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">null</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">)<br /><font color="#0000ff">    </font>{<br /><font color="#0000ff">      </font>_shippers.LoadNextPartialSetAsync();<br /><font color="#0000ff">    </font>}<br /></font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">   
else<br /></font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">
            <font color="#0000ff">    </font>{<br /></font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">     
this</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">.dataGrid1.ItemsSource
= _shippers;<br /></font>
        </font>
        <font face="Consolas" color="#0000ff" size="2">
          <font face="Consolas" color="#0000ff" size="2">
            <font face="Consolas" color="#0000ff" size="2">     
this</font>
          </font>
        </font>
        <font face="Consolas" size="2">
          <font face="Consolas" size="2">.dataGrid1.UpdateLayout();<br /><font color="#0000ff">    </font>}<br />
  }
</font>
        </font>
        <p>
Debug -&gt; Start Without Debugging<br />
 You should get a dialog box titled "Silverlight Project" that says:<br />
  "The Silverlight project you are about to debug uses web services. 
Calls to the web service will fail unless the Silverlight project is hosted in and
launched from the same web project that contains the web services.  Do you want
to debug anyway?"<br />
 Click "Yes"
</p>
        <p>
This application runs fine.  The warning dialog message was obviously inaccurate
and misleading.
</p>
        <p>
I wish I would have understood what this warning dialog was trying to say, but since
the remote OData service was working, I had no real choice but to ignore the dialog,
which would haunt me when trying to use the same application to call a local OData
service.
</p>
        <p>
I believe this dialog is trying to warn you that Silverlight has special constraints
when calling web services, but it's still not clear to me what those are.  Proceed
cautiously.
</p>
        <p>
Here is one way to successfully call a local OData webservice from Silverlight 4 in
Visual Studio 10:
</p>
        <p>
File -&gt; New -&gt; Project<br />
 Visual C# -&gt; Silverlight -&gt; Silverlight Application -&gt; OK<br />
  New Silverlight Application wizard<br />
   OK (Accept the defaults: ASP.NET Web Application Project, Silverlight
4, etc.)
</p>
        <p>
Right Click SilverlightApplication&lt;number&gt;.Web in Solution Explorer -&gt; Add
New Item...<br />
 Visual C# -&gt; Data -&gt; ADO.NET Entity Data Model -&gt; Add<br />
  Entity Data Model Wizard<br />
   Next (Generate from database - this assumes you have Northwind running
locally)<br />
   New Connection... -&gt; Point to your local Northwind Database Server
-&gt; Next<br />
   Select the Tables check box (to select all tables) -&gt; Finish
</p>
        <p>
Right Click SilverlightApplication&lt;number&gt;.Web in Solution Explorer -&gt; Add
New Item...<br />
 Visual C# -&gt; Web -&gt; WCF Data Service -&gt; Add
</p>
        <p>
In WcfDataService1.cs:<br />
 Replace " /* TODO: put your data source class name here */ " with "NorthwindEntities"
(no quotes)<br />
 Add the following line to the InitializeService method:
</p>
        <p>
  <font face="Consolas" size="2"><font face="Consolas" size="2">config.SetEntitySetAccessRule(</font></font><font face="Consolas" color="#a31515" size="2"><font face="Consolas" color="#a31515" size="2"><font face="Consolas" color="#a31515" size="2">"*"</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">, </font></font><font face="Consolas" color="#2b91af" size="2"><font face="Consolas" color="#2b91af" size="2"><font face="Consolas" color="#2b91af" size="2">EntitySetRights</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">.AllRead);
</font></font></p>
        <p>
Debug -&gt; Start Without Debugging
</p>
        <p>
Right Click References under SilverlightApplication&lt;number&gt; in Solution Explorer
-&gt; Add Service Reference...<br />
 Discover -&gt; Services In Solution (note the port number of the discovered
service, you will need it below)<br />
 Namespace: LocalNorthwindServiceReference<br />
 OK
</p>
        <p>
Stop the browser that was started above
</p>
        <p>
Follow the same basic steps as the first example above to modify MainPage except:<br />
 Replace RemoteNorthwindServiceReference with LocalNorthwindServiceReference 
<br />
 Replace "<a href="http://services.odata.org/Northwind/Northwind.svc/">http://services.odata.org/Northwind/Northwind.svc/</a>"
with "http://localhost:&lt;port number noted above&gt;/WcfDataService1.svc/"
</p>
        <p>
Debug -&gt; Start Without Debugging
</p>
        <p>
This application runs fine (without the warning dialog this time).
</p>
        <p>
It can be ridiculously difficult to get a local OData service working with Silverlight
4 if you don't carefully dance around the project setup issues.<br />
The warning dialog when you start debugging is nearly useless and the app will return
no data with no apparent errors if you setup the project incorrectly.
</p>
        <p>
Some references I found useful while building this sample:
</p>
        <p>
 MSDN: How to: Create the Northwind Data Service (WCF Data Services/Silverlight)<br />
 <a href="http://msdn.microsoft.com/en-us/library/cc838239(VS.95).aspx">http://msdn.microsoft.com/en-us/library/cc838239(VS.95).aspx</a></p>
        <p>
 Audrey PETIT's blog: Use OData data with WCF Data Services and Silverlight 4<br />
 <a href="http://msmvps.com/blogs/audrey/archive/2010/06/10/odata-use-odata-data-with-wcf-data-services-and-silverlight-4.aspx">http://msmvps.com/blogs/audrey/archive/2010/06/10/odata-use-odata-data-with-wcf-data-services-and-silverlight-4.aspx</a></p>
        <p>
 Darrel Miller's Bizcoder blog: World’s simplest OData service<br />
 <a href="http://www.bizcoder.com/index.php/2010/03/26/worlds-simplest-odata-service/">http://www.bizcoder.com/index.php/2010/03/26/worlds-simplest-odata-service/</a></p>
        <p>
Once you deploy your OData service to a real web hosting environment, you'll likely
need to do some special setup to access your OData service from Silverlight 4 (clientaccesspolicy.xml
/ crossdomain.xml):
</p>
        <p>
 Making a Service Available Across Domain Boundaries<br />
 <a href="http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx">http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx</a></p>
        <p>
Tremendous thanks go out to <a href="http://www.ignitionpointsolutions.com/Blog/tabid/56/Default.aspx">Scott
Davis of Ignition Point Solutions</a> for pointing me to the flawed project setup
as the reason I couldn't get this working initially.<br /></p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=4839bf08-5a1b-4b2a-954d-aa90d0f3f979" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using Linq with NHibernate : A Quick Start - Updated August 2010</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2010/08/01/UsingLinqWithNHibernateAQuickStartUpdatedAugust2010.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,d404eb9a-57bf-46e0-976a-9f81312ef5a8.aspx</id>
    <published>2010-08-01T04:24:48.9264527-07:00</published>
    <updated>2010-08-01T04:24:48.9264527-07:00</updated>
    <category term=".NET 3.5" label=".NET 3.5" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,NET35.aspx" />
    <category term="Castle ActiveRecord" label="Castle ActiveRecord" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,CastleActiveRecord.aspx" />
    <category term="Knowledge Base" label="Knowledge Base" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,KnowledgeBase.aspx" />
    <category term="NHibernate" label="NHibernate" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,NHibernate.aspx" />
    <category term="SQL Server" label="SQL Server" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,SQLServer.aspx" />
    <category term="Visual Studio 2008" label="Visual Studio 2008" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,VisualStudio2008.aspx" />
    <category term=".NET 4.0" label=".NET 4.0" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,NET40.aspx" />
    <category term="AFO" label="AFO" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,AFO.aspx" />
    <category term="Visual Studio 2010" label="Visual Studio 2010" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,VisualStudio2010.aspx" />
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
This post is an update to a post I made last September (~10 months ago):
</p>
        <p>
          <a href="http://www.capprime.com/software_development_weblog/PermaLink,guid,162facaa-a3b9-4dc5-b770-657e27e887ad.aspx">http://www.capprime.com/software_development_weblog/PermaLink,guid,162facaa-a3b9-4dc5-b770-657e27e887ad.aspx</a>
        </p>
        <p>
The biggest roadblock I ran into when writing that blog post is that ActiveWriter
doesn't work well with the Northwind database which had significant ripple effects
throughout the sample.
</p>
        <p>
That inspired me to spend quite a bit of time over the last 10 months to make the
Castle ActiveRecord code generation story better.
</p>
        <p>
So here is an updated sample using the free version of the <a href="http://www.agilityfororms.com/Home/Products/AfoCastleActiveRecordModelCodeGenerator/">Agility
for ORMs Castle ActiveRecord code generator</a> in place of ActiveWriter.
</p>
        <p>
--
</p>
        <p>
This is a quick guide to getting up and running with NHibernate and Linq quickly.
</p>
        <p>
We are going to assume our database already exists.  We are going to assume that
database is Northwind, and we are going to assume that we are doing database driven
design (as opposed to domain driven design).  Northwind setup is described below.
</p>
        <p>
We are going to use Visual Studio 2008 with Service Pack 1 and SQL Server 2008 Express. 
(Note: A web application variant of this should work with Visual Web Developer 2008
Express Edition resulting in a completely free development stack.  This sample
should also work fine in Visual Studio 2010, but you'll need to change the project
to target the .NET Full Profile instead of the .NET Client Profile.)
</p>
        <p>
Step 1:
</p>
        <p>
Download and install the Northwind database.
</p>
        <p>
Jeff Atwood provides approximate instructions here (ask specific questions in the
comments if you get stuck):
</p>
        <p>
          <a href="http://www.codinghorror.com/blog/archives/000434.html">http://www.codinghorror.com/blog/archives/000434.html</a>
        </p>
        <p>
Follow the path for installing the binary files from the command line.  I have
tested that the SQL 2005 instructions work on SQL 2008.
</p>
        <p>
          <br />
Step 2:
</p>
        <p>
Next Download Castle ActiveRecord.  The download link is available from here:
</p>
        <p>
          <a href="http://www.castleproject.org/castle/projects.html">http://www.castleproject.org/castle/projects.html</a>
        </p>
        <p>
At the time of writing, the current version is "2.1.2 (2010-01-31)".
</p>
        <p>
Unzip it and remember where you put it, you'll need that info in step 3.
</p>
        <p>
          <br />
Step 3:
</p>
        <p>
Start Visual Studio 2008
</p>
        <p>
We will create a new console application project:
</p>
        <p>
File -&gt; New -&gt; Project<br />
 Visual C# -&gt; Windows -&gt; Console Application<br />
  ConsoleApplication1 -&gt; OK
</p>
        <p>
We need to add the appropriate NHibernate &amp; Castle Active Record references:
</p>
        <p>
Solution Explorer<br />
 Right Click ConsoleApplication1 -&gt; References -&gt; Add<br />
  Browse Tab<br />
   Go to your Castle ActiveRecord download location and add:<br />
    Castle.ActiveRecord.dll<br />
    Castle.ActiveRecord.Linq.dll<br />
    Castle.DynamicProxy2.dll<br />
    NHibernate.dll<br />
    NHibernate.Linq.dll<br />
   Click OK
</p>
        <p>
And add a reference to System.Configuration as well:
</p>
        <p>
Solution Explorer<br />
 Right Click ConsoleApplication1 -&gt; References -&gt; Add<br />
  .NET Tab<br />
   System.Configuration<br />
  Click OK
</p>
        <p>
          <br />
Step 4:
</p>
        <p>
Download the free (aka Convention Only) version of the Agility for ORMs Castle ActiveRecord
code generator by registering and then downloading here:
</p>
        <p>
          <a href="http://www.agilityfororms.com/Apps/Register.aspx">http://www.agilityfororms.com/Apps/Register.aspx</a>
        </p>
        <p>
The current version is 1.0.0.4.
</p>
        <p>
          <br />
Step 5:
</p>
        <p>
Run the AFO Castle ActiveRecord code generator, specifying the correct connection
string for the Northwind database you setup in Step 1 above.
</p>
        <p>
Note the output directory where the generated files went, you'll need that info in
step 6.
</p>
        <p>
          <br />
Step 6:
</p>
        <p>
Add the generated files to the console application project.
</p>
        <p>
Solution Explorer<br />
 Right Click ConsoleApplication1 -&gt; Add -&gt; New Folder -&gt; DataLayer<br />
 Right Click DataLayer -&gt; Add -&gt; Existing Item...<br />
  Add all of the .cs files generated in Step 5.
</p>
        <p>
          <br />
Step 7:
</p>
        <p>
We will now add an Application Configuration File to the project and put the Northwind
Connection String into it:
</p>
        <p>
Solution Explorer<br />
 Right Click ConsoleApplication1 -&gt; Add -&gt; New Item...<br />
  Visual C# Items -&gt; General -&gt; Application Configuration File<br />
  Add
</p>
        <p>
Modify the file to look like this and use your specific DB connection info:
</p>
        <p>
--<br />
&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />
&lt;configuration&gt;<br />
  &lt;connectionStrings&gt;<br />
    &lt;add name="Northwind" connectionString="Data Source=.\SQLExpress;Initial
Catalog=Northwind;Trusted_Connection=True;"/&gt;<br />
  &lt;/connectionStrings&gt;<br />
&lt;/configuration&gt;<br />
--
</p>
        <p>
          <br />
Step 8:
</p>
        <p>
Open the main "Program.cs" class and add the following new method:
</p>
        <p>
        private static void InitializeNHibernateActiveRecord()<br />
        {<br />
            string connectionString
= System.Configuration.ConfigurationManager.ConnectionStrings["Northwind"].ToString();<br />
            InPlaceConfigurationSource
configuration = InPlaceConfigurationSource.Build(DatabaseType.MsSqlServer2008, connectionString);
</p>
        <p>
            ActiveRecordStarter.Initialize(System.Reflection.Assembly.GetExecutingAssembly(),
configuration);<br />
        }
</p>
        <p>
Add the following code to the Main Method:
</p>
        <p>
        static void Main(string[] args)<br />
        {<br />
            try<br />
            {<br />
               
InitializeNHibernateActiveRecord();
</p>
        <p>
               
using (new SessionScope())<br />
               
{<br />
                   
var queryToExecute = from oneProduct in ActiveRecordLinq.AsQueryable&lt;Product&gt;()<br />
                                        
select oneProduct;
</p>
        <p>
                   
foreach (Product oneProduct in queryToExecute.Take(5).ToList())<br />
                   
{<br />
                       
Console.WriteLine("ProductID=[" + oneProduct.ProductID + "] ProductName=[" + oneProduct.ProductName
+ "] Supplier CompanyName=[" + oneProduct.Supplier.CompanyName + "]");<br />
                   
}<br />
               
}<br />
            }<br />
            catch (Exception
oneException)<br />
            {<br />
               
Console.WriteLine("oneException=[" + oneException + "]");<br />
               
throw; // you can remove this if you'd rather the program exit "more normally"<br />
            }<br />
        }
</p>
        <p>
Add the following using statements at the top of Program.cs:
</p>
        <p>
using Castle.ActiveRecord;<br />
using Castle.ActiveRecord.Framework.Config;<br />
using Castle.ActiveRecord.Linq;
</p>
        <p>
using Model.Northwind;
</p>
        <p>
          <br />
Step 9:
</p>
        <p>
Copy the NHibernate.ByteCode.Castle.dll file from your Castle Active Record download
unzip directory to your projects bin\Debug\ folder.
</p>
        <p>
          <br />
Step 10:
</p>
        <p>
Run the application:
</p>
        <p>
Ctrl-F5 (Debug -&gt; Start Without Debugging)
</p>
        <p>
And you should see the following output:
</p>
        <p>
--<br />
ProductID=[1] ProductName=[Chai] Supplier CompanyName=[Exotic Liquids]<br />
ProductID=[2] ProductName=[Chang] Supplier CompanyName=[Exotic Liquids]<br />
ProductID=[3] ProductName=[Aniseed Syrup] Supplier CompanyName=[Exotic Liquids]<br />
ProductID=[4] ProductName=[Chef Anton's Cajun Seasoning] Supplier CompanyName=[New
Orleans Cajun Delights]<br />
ProductID=[5] ProductName=[Chef Anton's Gumbo Mix] Supplier CompanyName=[New Orleans
Cajun Delights]<br />
Press any key to continue . . .<br />
--
</p>
        <p>
We have successfully executed a join query through Linq.
</p>
        <p>
          <br />
Please note:
</p>
        <p>
You'll notice that the Agility for ORMs Castle ActiveRecord code generator only generated
5 class files in addition to a readme.txt file (there are 13 tables in Northwind which
would otherwise result in 11 class files).  Northwind is not a convention based
database due to use of assignable keys, surrogate keys, and composite keys. 
The free version of the AFO code generator only works with convention oriented database
tables and only 5 of the tables in Northwind follow conventions.  The readme.txt
file explains why the other tables were not generated.
</p>
        <p>
The commercial version ($30) of the AFO code generator will properly generate code
for all 13 tables in Northwind and is intended to support the entire feature set of
Castle ActiveRecord including things like Composite Keys, which aren't currently supported
by ActiveWriter.
</p>
        <p>
          <br />
Now that you have the basic NHibernate Linq infrastructure in place, there are plenty
of Linq examples and sample code available elsewhere.
</p>
        <p>
Enjoy!
</p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=d404eb9a-57bf-46e0-976a-9f81312ef5a8" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Looking for .NET developers to mentor in Minnesota</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2010/04/17/LookingForNETDevelopersToMentorInMinnesota.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,2c305ac6-873b-4ce7-a3e2-5613e77f361c.aspx</id>
    <published>2010-04-17T02:42:27.8768647-07:00</published>
    <updated>2010-04-17T02:42:27.8768647-07:00</updated>
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Are you a .NET developer in the Twin Cities, Minnesota area that would be interested
in having a mentor?  I'm looking for .NET developers to mentor.
</p>
        <p>
I don't really have any specific criteria in mind and I don't expect that enough people
read my blog/twitter that I will be overwhelmed with requests.
</p>
        <p>
Ambition is probably the quality I'm looking for most.
</p>
        <p>
If you are interested, contact me via e-mail and we can work out whether it's a good
fit.
</p>
        <p>
You can learn more about me here: <a href="http://www.capprime.com/About.htm">http://www.capprime.com/About.htm</a></p>
        <p>
You can contact me through my contact page here: <a href="http://www.capprime.com/Contact.htm">http://www.capprime.com/Contact.htm</a></p>
        <p>
I will try to come back and update this blog post if/when I no longer have time to
mentor additional people, so consider this offer open for the foreseeable future.
</p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=2c305ac6-873b-4ce7-a3e2-5613e77f361c" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using SMO (and failing) to get the SqlDataType of a UserDefinedDataType</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2010/03/15/UsingSMOAndFailingToGetTheSqlDataTypeOfAUserDefinedDataType.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,14f458ec-f15c-4406-aff7-6942bd9fa92f.aspx</id>
    <published>2010-03-15T05:56:31.1125-07:00</published>
    <updated>2010-03-15T05:56:31.1125-07:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,KnowledgeBase.aspx" />
    <category term="SQL Server" label="SQL Server" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,SQLServer.aspx" />
    <category term="Visual Studio 2008" label="Visual Studio 2008" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,VisualStudio2008.aspx" />
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,SQLServer2008.aspx" />
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Apparently SMO can't get the SqlDataType of a UserDefinedDataType.
</p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/ms162169.aspx">SQL Server Management
Objects (SMO)</a> is a pretty powerful API into Microsoft SQL Server.  I've
been pretty happy using it in various scenarios over the years.
</p>
        <p>
Recently, I was surprised to find out that SMO can't get the SqlDataType underlying
a UserDefinedDataType.  This is reproducible using the Microsoft Pubs sample
database.
</p>
        <p>
Attempt #1:
</p>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
string
</p>
          </font>
        </font>
        <font color="#000000" size="2"> databaseName = </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"pubs"</font>
        </font>
        <font size="2">
          <font color="#000000">;<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">string</font>
        </font>
        <font color="#000000" size="2"> connectionString
= System.Configuration.</font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">ConfigurationManager</font>
        </font>
        <font size="2">
          <font color="#000000">.ConnectionStrings[databaseName].ToString();</font>
        </font>
        <p>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">SqlConnection</font>
          </font>
          <font color="#000000" size="2"> oneSqlConnection
= </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">SqlConnection</font>
          </font>
          <font size="2">
            <font color="#000000">(connectionString);<br /></font>
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ServerConnection</font>
          </font>
          <font color="#000000" size="2"> oneServerConnection
= </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ServerConnection</font>
          </font>
          <font size="2">
            <font color="#000000">(oneSqlConnection);<br /></font>
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Server</font>
          </font>
          <font color="#000000" size="2"> oneServer
= </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Server</font>
          </font>
          <font size="2">
            <font color="#000000">(oneServerConnection);<br /></font>
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Database</font>
          </font>
          <font color="#000000" size="2"> oneDatabase
= </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Database</font>
          </font>
          <font size="2">
            <font color="#000000">(oneServer,
databaseName);<br /></font>oneDatabase.Refresh();
</font>
        </p>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">
            <p>
UserDefinedDataType
</p>
          </font>
        </font>
        <font color="#000000" size="2"> tidUserDefinedDataType =<br />
 </font>
        <font color="#000000" size="2">   </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">new</font>
        </font>
        <font color="#000000" size="2"> Microsoft.SqlServer.Management.Smo.</font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">UserDefinedDataType</font>
        </font>
        <font color="#000000" size="2">(oneDatabase, </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"tid"</font>
        </font>
        <font color="#000000" size="2">, </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"dbo"</font>
        </font>
        <font size="2">
          <font color="#000000">);<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">bool</font>
        </font>
        <font color="#000000" size="2"> initializeDidSucceed
= tidUserDefinedDataType.Initialize(</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">true</font>
        </font>
        <font size="2">
          <font color="#000000">);</font>
        </font>
        <p>
In this scenario, for reasons unknown to me, initializeDidSucceed is false!
</p>
        <p>
Now, if we try to access tidUserDefinedDataType.SystemType which seems like the appropriate
data item, we get this exception:
</p>
        <p>
Microsoft.SqlServer.Management.Smo.PropertyNotSetException: To accomplish this action,
set property SystemType. 
<br />
   at Microsoft.SqlServer.Management.Smo.SqlSmoObject.OnPropertyMissing(String
propname, Boolean useDefaultValue) 
<br />
   at Microsoft.SqlServer.Management.Smo.PropertyCollection.RetrieveProperty(Int32
index, Boolean useDefaultOnMissingValue) 
<br />
   at Microsoft.SqlServer.Management.Smo.PropertyCollection.GetValueWithNullReplacement(String
propertyName, Boolean throwOnNullValue, Boolean useDefaultOnMissingValue) 
<br />
   at Microsoft.SqlServer.Management.Smo.UserDefinedDataType.get_SystemType() 
</p>
        <p>
          <br />
Attempt #2:
</p>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
string
</p>
          </font>
        </font>
        <font color="#000000" size="2"> databaseName = </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"pubs"</font>
        </font>
        <font size="2">
          <font color="#000000">;<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">string</font>
        </font>
        <font color="#000000" size="2"> connectionString
= System.Configuration.</font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">ConfigurationManager</font>
        </font>
        <font size="2">
          <font color="#000000">.ConnectionStrings[databaseName].ToString();</font>
        </font>
        <p>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">SqlConnection</font>
          </font>
          <font color="#000000" size="2"> oneSqlConnection
= </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">SqlConnection</font>
          </font>
          <font size="2">
            <font color="#000000">(connectionString);<br /></font>
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ServerConnection</font>
          </font>
          <font color="#000000" size="2"> oneServerConnection
= </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ServerConnection</font>
          </font>
          <font size="2">
            <font color="#000000">(oneSqlConnection);</font>
          </font>
        </p>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">
            <p>
Server
</p>
          </font>
        </font>
        <font color="#000000" size="2"> oneServer = </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">new</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">Server</font>
        </font>
        <font size="2">
          <font color="#000000">(oneServerConnection);<br /></font>
        </font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">Database</font>
        </font>
        <font color="#000000" size="2"> oneDatabase
= </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">new</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">Database</font>
        </font>
        <font size="2">
          <font color="#000000">(oneServer,
databaseName);<br /></font>oneDatabase.Refresh();
</font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">
            <p>
Table
</p>
          </font>
        </font>
        <font color="#000000" size="2"> oneTable = </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">new</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">Table</font>
        </font>
        <font color="#000000" size="2">(oneDatabase, </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"titles"</font>
        </font>
        <font color="#000000" size="2">, </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"dbo"</font>
        </font>
        <font size="2">
          <font color="#000000">);<br /></font>oneTable.Refresh();
</font>
        <p>
Now the following values are returned:
</p>
        <p>
oneTable.Columns[0].Name                            
= title_id<br />
oneTable.Columns[0].DataType.Name               =
tid<br />
oneTable.Columns[0].DataType.SqlDataType      = UserDefinedDataType<br />
oneTable.Columns[0].DataType.MaximumLength  = 6
</p>
        <p>
So, we can successfully get the length of the underlying data type, but we can't get
the SqlDataType.
</p>
        <p>
          <br />
Attempt #3:
</p>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
USE
</p>
          </font>
        </font>
        <font size="2">
          <font color="#000000"> pubs</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
DECLARE
</p>
          </font>
        </font>
        <font color="#000000" size="2"> @CurrentSchemaName </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">VARCHAR</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">(</font>
        </font>
        <font color="#000000" size="2">128</font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">)<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">DECLARE</font>
        </font>
        <font color="#000000" size="2"> @UserDefinedDataTypeName </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">VARCHAR</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">(</font>
        </font>
        <font color="#000000" size="2">128</font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">)
</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
SET
</p>
          </font>
        </font>
        <font color="#000000" size="2"> @CurrentSchemaName </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">'dbo'<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">SET</font>
        </font>
        <font color="#000000" size="2"> @UserDefinedDataTypeName </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">'tid'
</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
SELECT
</p>
          </font>
        </font>
        <font size="2">
          <font color="#000000"> name<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">FROM</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">types<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">WHERE</font>
        </font>
        <font color="#000000" size="2"> user_type_id </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=<br /></font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2"> 
(<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">  
SELECT</font>
        </font>
        <font size="2"> system_type_id<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">  
FROM</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">types<br /></font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">  
  INNER</font>
        </font>
        <font size="2">
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">JOIN</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">schemas<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">      
ON</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">types</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#ff00ff" size="2">
          <font color="#ff00ff" size="2">schema_id</font>
        </font>
        <font size="2">
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">schemas</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#ff00ff" size="2">
          <font color="#ff00ff" size="2">schema_id<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">  
WHERE</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">schemas</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font size="2">name </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font size="2"> @CurrentSchemaName<br /></font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">    
AND</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">types</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font size="2">name </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font size="2"> @UserDefinedDataTypeName<br /></font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">  )
</font>
        </font>
        <p>
Using straight SQL, we appear to be able to get the answer we are looking for: "varchar".
</p>
        <p>
          <br />
I wonder why SMO is missing this capability?
</p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=14f458ec-f15c-4406-aff7-6942bd9fa92f" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Options for running T4 templates from .NET code</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2010/02/20/OptionsForRunningT4TemplatesFromNETCode.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,104d9faf-5780-42ca-88e5-c04cb88f61b3.aspx</id>
    <published>2010-02-20T08:09:50.139-07:00</published>
    <updated>2010-03-07T04:44:48.01875-07:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,KnowledgeBase.aspx" />
    <category term="T4" label="T4" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,T4.aspx" />
    <category term="Tools" label="Tools" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,Tools.aspx" />
    <category term="Visual Studio 2008" label="Visual Studio 2008" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,VisualStudio2008.aspx" />
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx">T4
Templates</a> are really nice given that the tools are included free in Visual
Studio (the Express Editions of Visual Studio appear to have some under-documented
limitations when it comes to T4 support).
</p>
        <p>
The primary way that T4 templates are processed is from within Visual Studio. 
That works pretty well.
</p>
        <p>
What if you want to process a T4 template outside of Visual Studio (as part of an
automated build process, for example)?
</p>
        <p>
The easiest option for running a T4 template outside of Visual Studio is through the <a href="http://msdn.microsoft.com/en-us/library/bb126245.aspx">TextTransform.exe</a> (custom
T4 host) command line tool.
</p>
        <p>
The main difficulty I've encountered using the TextTransform.exe command line tool
is error handling.
</p>
        <p>
Here's a sample error (written to StandardError):<br />
--<br />
MyT4Template.tt(0,0) : error : Running transformation: System.InvalidCastException:
Unable to cast object of type 'Microsoft.VisualStudio.TextTemplating.CommandLine.CommandLineHost'
to type 'System.IServiceProvider'.<br />
   at Microsoft.VisualStudio.TextTemplatingc7fe0d0277b54f7c95c25936373918ff.GeneratedTextTransformation.TransformText()<br />
--
</p>
        <p>
Notice the (0,0).  That is where the line and column numbers would normally go
for where the error occurred.  Also notice the stack trace contains no useful
information (the error message, at least, in this case *is* useful).
</p>
        <p>
The other downsides of using TextTransform.exe are similar to situations where you
are calling out to an EXE file from code as opposed to working against an API.
</p>
        <p>
The main positive I've encountered using the TextTransform.exe command line tool is
if the template processes okay in Visual Studio, it will likely process okay using
TextTransform.exe.  The above error was generated by using a template that tried
to reference EnvDTE.DTE which works fine from within Visual Studio, but doesn’t necessarily
make sense to do outside of Visual Studio.
</p>
        <p>
          <br />
As an alternative, you might attempt to use the Visual Studio T4 engine from .NET
code like so:<br />
--<br /><font color="#2b91af" size="2"><font color="#2b91af" size="2">ITextTemplatingEngineHost</font></font><font color="#000000" size="2"> host
= </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"><font color="#000000"> Microsoft.VisualStudio.TextTemplating.VSHost.TextTemplatingService();<br /></font></font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ITextTemplatingEngine</font></font><font color="#000000" size="2"> engine
= </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font color="#000000" size="2"> Microsoft.VisualStudio.TextTemplating.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Engine</font></font><font size="2"><font color="#000000">();<br /></font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">string</font></font><font size="2"><font color="#000000"> outputCode
= engine.ProcessTemplate(inputContent, host);</font></font><br />
--
</p>
        <p>
But that won't work.  You will get these compile time errors:<br />
--<br />
The type 'Microsoft.VisualStudio.TextTemplating.VSHost.TextTemplatingService' has
no constructors defined<br />
'Microsoft.VisualStudio.TextTemplating.VSHost.TextTemplatingService' is inaccessible
due to its protection level<br />
--
</p>
        <p>
          <br />
The hardest option for running a T4 template outside of Visual Studio is by implementing
the ITextTemplatingEngineHost interface.  There is an example of how to do that
here:
</p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/bb126579.aspx">Walkthrough: Creating
a Custom Text Template Host</a>
        </p>
        <p>
The problem with that example is that it fails for multiple distinct reasons for templates
that run just fine in Visual Studio and from TextTransform.exe.  It doesn’t appear
to be even close to a full featured ITextTemplatingEngineHost implementation (it’s
quite a "teaser" of a sample, enough to show it has potential, but not enough to show
you how far from reality you are).
</p>
        <p>
Mono provides an alternative implementation of the ITextTemplatingEngineHost interface
here:
</p>
        <p>
          <a href="http://anonsvn.mono-project.com/viewvc/trunk/monodevelop/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs">http://anonsvn.mono-project.com/viewvc/trunk/monodevelop/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs</a>
        </p>
        <p>
And while that fails less often on templates that run just fine in Visual Studio,
it still fails in multiple ways.  I appreciate what the Mono folks have done,
but for this use case (trying to run T4 templates outside of Visual Studio), there
isn’t much value add.
</p>
        <p>
The advantage of using a custom ITextTemplatingEngineHost host implementation is you
have significantly more power and control than you have with TextTransform.exe. 
TextTransform.exe has a limited input/output/error mechanism and its internals are
not very extensible/customizable.
</p>
        <p>
The disadvantage of using a custom ITextTemplatingEngineHost host implementation (as
opposed to TextTransform.exe) is that you possibly have to write a decent amount of
code against an undocumented system before your T4 template that processes fine in
Visual Studio will process equivalently from .NET code (this will depend greatly on
the contents of your T4 template).
</p>
        <p>
If anyone is aware of other (free or commercial) custom implementations of the ITextTemplatingEngineHost
interface that are usable from .NET code, please let me know!<br /></p>
        <p>
          <strong>Update March 7, 2010:</strong> Apparently this will be much easier in Visual
Studio 2010:
</p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/ee844259(VS.100).aspx">Generating
Text Files at Run Time by Using Preprocessed Text Templates</a>
        </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=104d9faf-5780-42ca-88e5-c04cb88f61b3" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using NHibernate Validator Event Based Validation</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2010/01/25/UsingNHibernateValidatorEventBasedValidation.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,99297ab9-2919-48c5-a99a-a04893437df6.aspx</id>
    <published>2010-01-25T07:42:45.5555-07:00</published>
    <updated>2010-01-25T07:42:45.5555-07:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,KnowledgeBase.aspx" />
    <category term="NHibernate" label="NHibernate" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,NHibernate.aspx" />
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
The main documentation for the NHibernate Validator is here:
</p>
        <p>
          <a href="http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx">http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx</a>
        </p>
        <p>
And it alludes to the fact that you can configure the validator to be called automatically
before Insert/Update.
</p>
        <p>
However, it fails to clearly communicate how to do this.
</p>
        <p>
The important missing piece is that "ValidatorInitializer.Initialize()" needs to be
called before the session factory gets created.
</p>
        <p>
Here is some working sample code:
</p>
        <p>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">string</font>
          </font>
          <font size="2">
            <font color="#000000"> connectionString
=<br />
  </font>System.Configuration.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ConfigurationManager</font>
          </font>
          <font size="2">.ConnectionStrings[</font>
          <font color="#a31515" size="2">
            <font color="#a31515" size="2">"Northwind"</font>
          </font>
          <font size="2">].ToString();
</font>
        </p>
        <p>
NHibernate.Validator.Engine.<font color="#2b91af" size="2"><font color="#2b91af" size="2">ValidatorEngine</font></font><font size="2"> oneValidatorEngine
=<br />
  </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"> NHibernate.Validator.Engine.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ValidatorEngine</font></font><font size="2">();</font></p>
        <p>
          <font size="2">NHibernate.Validator.Cfg.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">INHVConfiguration</font>
          </font>
          <font size="2"> oneINHVConfiguration
=<br />
  </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font size="2"> NHibernate.Validator.Cfg.Loquacious.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">FluentConfiguration</font>
          </font>
          <font size="2">();<br /></font>
          <font color="#008000" size="2">
            <font color="#008000" size="2">//<font color="#008000" size="2"><font color="#008000" size="2">oneINHVConfiguration</font></font>.Properties[NHibernate.Validator.Cfg.Environment.AutoregisterListeners]
= "true";<br /></font>
          </font>
          <font size="2">oneINHVConfiguration.Properties[NHibernate.Validator.Cfg.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Environment</font>
          </font>
          <font size="2">.ValidatorMode]
= </font>
          <font color="#a31515" size="2">
            <font color="#a31515" size="2">"UseExternal"</font>
          </font>
          <font size="2">;<br />
oneINHVConfiguration.Mappings.Add(</font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font size="2"> NHibernate.Validator.Cfg.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">MappingConfiguration</font>
          </font>
          <font size="2">(</font>
          <font color="#a31515" size="2">
            <font color="#a31515" size="2">"YourNamespaceGoesHere"</font>
          </font>
          <font size="2">, </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">null</font>
          </font>
          <font size="2">));<br />
oneValidatorEngine.Configure(oneINHVConfiguration);
</font>
        </p>
        <p>
NHibernate.Cfg.<font color="#2b91af" size="2"><font color="#2b91af" size="2">Configuration</font></font><font size="2"> nHibernateConfiguration
= </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"> NHibernate.Cfg.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Configuration</font></font><font size="2">();<br />
nHibernateConfiguration.SetProperty(NHibernate.Cfg.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Environment</font></font><font size="2">.ConnectionString,<br />
  </font><font size="2">connectionString);<br /></font><font size="2">nHibernateConfiguration.SetProperty(NHibernate.Cfg.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Environment</font></font><font size="2">.Dialect,<br />
  </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">typeof</font></font><font size="2">(NHibernate.Dialect.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">MsSql2005Dialect</font></font><font size="2">).AssemblyQualifiedName);<br /></font><font size="2">nHibernateConfiguration.SetProperty(NHibernate.Cfg.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Environment</font></font><font size="2">.ProxyFactoryFactoryClass,<br />
  </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">typeof</font></font><font size="2">(NHibernate.ByteCode.Castle.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ProxyFactoryFactory</font></font><font size="2">).AssemblyQualifiedName);<br />
nHibernateConfiguration.AddAssembly(System.Reflection.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Assembly</font></font><font size="2">.GetCallingAssembly());</font></p>
        <p>
          <font size="2">NHibernate.Validator.Cfg.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ValidatorInitializer</font>
          </font>
          <font size="2">.Initialize(nHibernateConfiguration,
oneValidatorEngine);
</font>
        </p>
        <p>
NHibernate.<font color="#2b91af" size="2"><font color="#2b91af" size="2">ISessionFactory</font></font><font size="2"> oneISessionFactory
= nHibernateConfiguration.BuildSessionFactory();</font></p>
        <p>
 
</p>
        <p>
This code throws an NHibernate.PropertyValueException instead of an NHibernate.Exceptions.GenericADOException
/ System.Data.SqlClient.SqlException, which is what we want in this case.  Another
exception I've seen the NHibernate Validator throw is NHibernate.Validator.Exceptions.InvalidStateException.
</p>
        <p>
It's much easier and more pleasant to try to recover from a validation error than
a database error.
</p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=99297ab9-2919-48c5-a99a-a04893437df6" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Castle ActiveRecord and the InPlaceConfigurationSource</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/2009/09/27/CastleActiveRecordAndTheInPlaceConfigurationSource.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,2e2ba2a1-3e62-4ff3-8247-27860d8873d6.aspx</id>
    <published>2009-09-27T05:05:50.3725-07:00</published>
    <updated>2009-09-27T05:05:50.3725-07:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,KnowledgeBase.aspx" />
    <category term="NHibernate" label="NHibernate" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,NHibernate.aspx" />
    <category term="Castle ActiveRecord" label="Castle ActiveRecord" scheme="http://www.capprime.com/software_development_weblog/CategoryView,category,CastleActiveRecord.aspx" />
    <author>
      <name>Michael Maddox</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I like to store my application's configuration in app.config or web.config (depending
on the project type) which is pretty standard for .NET applications.  Therefore,
I'm not a big fan of ActiveRecord's XmlConfigurationSource.
</p>
        <p>
That said, the InPlaceConfigurationSource is somewhat difficult to puzzle out. 
After reading the source code, I was able to bend it to my will.
</p>
        <p>
In particular, I like this syntax well enough:
</p>
        <p>
InPlaceConfigurationSource configuration =<br />
    InPlaceConfigurationSource.Build(DatabaseType.MSSQLServer2005,
connectionString);
</p>
        <p>
It lets me setup my connection string and database type and default most everything
else.
</p>
        <p>
The "problem" is that I can't then do something clean and simple like this:
</p>
        <p>
configuration.Add("show_sql", true);
</p>
        <p>
Instead I have to do this:
</p>
        <p>
Castle.Core.Configuration.MutableConfiguration oneMutableConfiguration =<br />
  (Castle.Core.Configuration.MutableConfiguration)configuration.GetConfiguration(typeof(ActiveRecordBase));<br />
oneMutableConfiguration.Children.Add(new<br />
  Castle.Core.Configuration.MutableConfiguration("show_sql", true.ToString()));<br />
configuration.Add(typeof(ActiveRecordBase), oneMutableConfiguration);
</p>
        <p>
Which works, but it's not the friendliest API to program against.
</p>
        <p>
Be careful, the "Add" method on InPlaceConfigurationSource is not really "Add". 
It is really "Replace".
</p>
        <p>
The other main alternative for using InPlaceConfigurationSource is something like
this, which is useful for when I can't just use the defaults:
</p>
        <p>
IDictionary&lt;string, string&gt; properties =<br />
  new System.Collections.Generic.Dictionary&lt;string, string&gt;();<br />
properties.Add("connection.driver_class", "NHibernate.Driver.SqlClientDriver");<br />
properties.Add("connection.provider",<br />
  "NHibernate.Connection.DriverConnectionProvider");<br />
properties.Add("proxyfactory.factory_class",<br />
  "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
</p>
        <p>
properties.Add("dialect", "NHibernate.Dialect.MsSql2005Dialect");<br />
properties.Add("connection.connection_string", connectionString);
</p>
        <p>
properties.Add("show_sql", true.ToString());
</p>
        <p>
InPlaceConfigurationSource configuration = new InPlaceConfigurationSource();<br />
configuration.Add(typeof(ActiveRecordBase), (IDictionary&lt;string, string&gt;)properties);
</p>
        <p>
          <br />
This was written and tested against "ActiveRecord 2.0 - August 1st, 2009".
</p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=2e2ba2a1-3e62-4ff3-8247-27860d8873d6" />
      </div>
    </content>
  </entry>
</feed>