<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-2285278671879033267</atom:id><lastBuildDate>Sun, 20 Nov 2011 14:18:07 +0000</lastBuildDate><category>xml</category><category>winforms</category><category>devexpress</category><category>cloud</category><category>windowsvista</category><category>visualstudio</category><category>xpo</category><category>postsharp</category><category>eco</category><category>resharper</category><category>production</category><category>vistadb</category><title>Atlantic Breeze</title><description>A .Net view onto the Atlantic</description><link>http://kearon.blogspot.com/</link><managingEditor>noreply@blogger.com (Sean Kearon)</managingEditor><generator>Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AtlanticBreeze" /><feedburner:info uri="atlanticbreeze" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FAtlanticBreeze" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FAtlanticBreeze" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FAtlanticBreeze" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/AtlanticBreeze" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAtlanticBreeze" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAtlanticBreeze" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FAtlanticBreeze" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-6400886466514876665</guid><pubDate>Thu, 28 Jul 2011 20:17:00 +0000</pubDate><atom:updated>2011-07-28T21:20:28.979+01:00</atom:updated><title>RavenDB &amp; NServiceBus -</title><description>&lt;p&gt;The upcoming version 3.0 of everyone’s favourite service bus, &lt;a href="http://www.nservicebus.com" target="_blank"&gt;NServiceBus&lt;/a&gt;, will now use &lt;a href="http://ravendb.net/" target="_blank"&gt;RavenDB&lt;/a&gt; for saga persistence.&amp;nbsp; This makes it even easier to work with sagas in NSB.&lt;/p&gt; &lt;p&gt;Very cool!&amp;nbsp; Even better than that, it looks like RavenDB will be available for NServiceBus Express users too.&amp;nbsp; You can read Udi’s comment &lt;a href="http://www.udidahan.com/2011/07/22/nservicebus-and-ravendb-better-together/comment-page-1/#comment-38024" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Big thanks to Ayende and Udi for getting these two elegant technologies together like this.&amp;nbsp; &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-6400886466514876665?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/61tvyaLJ4AA/ravendb-nservicebus.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2011/07/ravendb-nservicebus.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-7501879205779358317</guid><pubDate>Sun, 27 Feb 2011 21:07:00 +0000</pubDate><atom:updated>2011-05-22T09:54:10.054+01:00</atom:updated><title>Mocking DbContext Entity Framework 4 Code First CTP5 with NSubstitute</title><description>Take an Entity Framework 4 Code First model, something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; Customer&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; Id { get; set; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; Name { get; set; }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; CustomerContext : DbContext, ICustomerContext&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; DbSet&amp;lt;Customer&amp;gt; Customers { get; set; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;br /&gt;
I now want to write some tests and I'm going to mock the DbContext using &lt;a href="http://http//nsubstitute.github.com/" target="_blank"&gt;NSubstitute&lt;/a&gt;. &amp;nbsp;I first try something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [Test]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; can_mock_customer_context()&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;    var context = Substitute.For&amp;lt;CustomerContext&amp;gt;();&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;    context.Customers.Returns(&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;       &lt;span style="color: blue;"&gt;new&lt;/span&gt; DbSet&amp;lt;Customer&amp;gt;(&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;          &lt;span style="color: blue;"&gt;new&lt;/span&gt;[]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;          {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;             &lt;span style="color: blue;"&gt;new&lt;/span&gt; Customer {Name = &lt;span style="color: #006080;"&gt;"Sean"&lt;/span&gt;}&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;          })&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;       );&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;    Assert.AreEqual(1, context.Customers.Count());&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
The problem is that the DbSet constructor is internal (as of EF4 Code First CTP5). &amp;nbsp;So, let's abstract our DB access to a simple interface and replace DbSet&amp;lt;T&amp;gt; with the &lt;a href="http://msdn.microsoft.com/en-us/library/bb351562.aspx" target="_blank"&gt;IQueryable&amp;lt;T&amp;gt;&lt;/a&gt; interface,&amp;nbsp;ending up with the below:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;interface&lt;/span&gt; ICustomerContext&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;    IQueryable&amp;lt;Customer&amp;gt; Customers { get; set; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
This interface can be implemented like so:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; CustomerContext : DbContext, ICustomerContext&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;   {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;      &lt;span style="color: blue;"&gt;public&lt;/span&gt; DbSet&amp;lt;Customer&amp;gt; Customers { get; set; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;      IQueryable&amp;lt;Customer&amp;gt; ICustomerContext.Customers { get { &lt;span style="color: blue;"&gt;return&lt;/span&gt; Customers; } }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;   }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
Now all we need to do is to use an implementation of &lt;a href="http://msdn.microsoft.com/en-us/library/bb351562.aspx" target="_blank"&gt;IQueryable&amp;lt;T&amp;gt;&lt;/a&gt; in our mock. &amp;nbsp;I'm going to use&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/cc190116.aspx" target="_blank"&gt;EnumerableQuery&amp;lt;T&amp;gt;&lt;/a&gt; which gives me the following test that now passes:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [Test]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; can_mock_customer_context()&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;    var context = Substitute.For&amp;lt;ICustomerContext&amp;gt;();&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;    context.Customers.Returns(&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;       &lt;span style="color: blue;"&gt;new&lt;/span&gt; EnumerableQuery&amp;lt;Customer&amp;gt;(&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;          &lt;span style="color: blue;"&gt;new&lt;/span&gt;[]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;          {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;             &lt;span style="color: blue;"&gt;new&lt;/span&gt; Customer {Name = &lt;span style="color: #006080;"&gt;"Sean"&lt;/span&gt;}&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;          })&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;       );&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;    Assert.AreEqual(1, context.Customers.Count());&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;    }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
I'm new to&amp;nbsp;&lt;a href="http://http//nsubstitute.github.com/"&gt;NSubstitute&lt;/a&gt;&amp;nbsp;but it seem to be the lowest friction mocking library out there. &amp;nbsp;Just perfect for use with Entity Framework 4 Code First - certainly the lowest friction ORM there is today!&lt;br /&gt;
&lt;br /&gt;
Note that we could have used the&amp;nbsp;&lt;a href="http://martinfowler.com/eaaCatalog/repository.html"&gt;repository pattern&lt;/a&gt;&amp;nbsp;to wrap the DbContext&amp;nbsp;instead of a simple interface, the approach is almost identical.&lt;br /&gt;
&lt;br /&gt;
Update: Ro Miller has an alternative approach using fakes that does a better job of surfacing IDbSet&lt;t&gt;. &amp;nbsp;Check it out here:&amp;nbsp;&lt;a href="http://romiller.com/2010/09/07/ef-ctp4-tips-tricks-testing-with-fake-dbcontext/"&gt;http://romiller.com/2010/09/07/ef-ctp4-tips-tricks-testing-with-fake-dbcontext/&lt;/a&gt;.&lt;/t&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-7501879205779358317?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/C8wz26ER8F0/mocking-entity-framework-4-code-first.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>4</thr:total><feedburner:origLink>http://kearon.blogspot.com/2011/02/mocking-entity-framework-4-code-first.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-4525629588746665978</guid><pubDate>Thu, 17 Feb 2011 20:05:00 +0000</pubDate><atom:updated>2011-02-17T20:07:05.160Z</atom:updated><title>Package Manager With Source Download</title><description>&lt;p&gt;I was skinning up some code and I used my &lt;a href="http://nuget.codeplex.com/" target="_blank"&gt;package&lt;/a&gt; &lt;a href="http://www.openwrap.org/" target="_blank"&gt;manager&lt;/a&gt; of choice to add &lt;a href="http://nlog-project.org/" target="_blank"&gt;NLog&lt;/a&gt; to the project.&amp;nbsp; All good, very easy and away I coded.&lt;/p&gt; &lt;p&gt;The project required a single DLL as an output.&amp;nbsp; So, I thought hey – I’ll use Paul Stovell’s &lt;a href="http://www.paulstovell.com/tape" target="_blank"&gt;Tape&lt;/a&gt; to save using &lt;a href="http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx" target="_blank"&gt;ILMerge&lt;/a&gt; in the build.&amp;nbsp; Good plan, but after 5 minutes browsing the NLog source on GitHub it realised I was not sure how to find the version I needed.&amp;nbsp; That’s fine, ILMerge is pretty easy to use so I used the build to save the day.&lt;/p&gt; &lt;p&gt;On the same day (today) I read &lt;a href="http://blogs.jetbrains.com/dotnet/2011/02/resharper-6-bundles-decompiler-free-standalone-tool-to-follow" target="_blank"&gt;this post&lt;/a&gt; about ReSharper 6 features and suddenly realised how powerful it would be for package managers to be able to give me the source, not just binaries.&amp;nbsp; Now that’s a killer feature and would be even better if the source came with a single file option so I didn’t even have to run &lt;a href="http://www.paulstovell.com/tape" target="_blank"&gt;Tape&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Oh, please, soon…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-4525629588746665978?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/BQryQVrUTW4/package-manager-with-source-download.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>2</thr:total><feedburner:origLink>http://kearon.blogspot.com/2011/02/package-manager-with-source-download.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-836136502342039711</guid><pubDate>Thu, 03 Feb 2011 01:19:00 +0000</pubDate><atom:updated>2011-02-03T08:25:36.985Z</atom:updated><title>A Better Deal</title><description>Red Gate are now going to charge for &lt;a href="http://www.lutzroeder.com/"&gt;Lutz Roeder’s&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/.NET_Reflector"&gt;Reflector&lt;/a&gt;.&amp;nbsp; This tool has been free for it's life – more years than I care to remember.&amp;nbsp; Its as much part of a software developer’s toolkit as a hammer is part of a builder’s toolkit.&lt;br /&gt;
&lt;br /&gt;
I have dealt with Red Gate as part of a very small company and as part of a very large company.&amp;nbsp; I am sorry to say that each time I have come away feeling less than happy. &amp;nbsp;Any company that sends be a maintenance bill at the end of year one that &lt;em&gt;exceeds&lt;/em&gt; &lt;em&gt;my original purchase price &lt;/em&gt;isn't going to make me happy to deal with them!&lt;br /&gt;
&lt;br /&gt;
Reading Red Gates’ &lt;a href="http://www.neildavidson.com/dontjustrollthedice.html"&gt;pricing strategy&lt;/a&gt;, written by their co-founder, Neil Davidson, I struggle to believe their other CEO, Simon Galbraith, when he says how sorry he is &lt;a href="http://www.youtube.com/watch?v=TKnEjiSGZLA"&gt;about charging for Reflector&lt;/a&gt;.&amp;nbsp; I just kept thinking that they just want my cash - like the other times I’ve dealt with them.&lt;br /&gt;
&lt;br /&gt;
Maybe Galbraith and Davidson should go and listen to &lt;a href="http://sethgodin.typepad.com/seths_blog/2010/08/the-right-price-the-first-time.html"&gt;Seth Godin’s pricing advice&lt;/a&gt;.&amp;nbsp; Maybe then I’d want to buy stuff from them!&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
35USD is good value for Reflector and I may have to buy a copy.&amp;nbsp; I’d really just rather buy from another company and get a better deal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-836136502342039711?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/YNPvZNQaxuA/better-deal.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>1</thr:total><feedburner:origLink>http://kearon.blogspot.com/2011/02/better-deal.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-2545162448055848762</guid><pubDate>Sat, 23 Oct 2010 14:12:00 +0000</pubDate><atom:updated>2010-10-24T07:54:58.570+01:00</atom:updated><title>Install the Full .Net 4 Framework with Tarma Installer</title><description>&lt;p&gt;If you haven’t seen &lt;a href="http://www.tarma.com/" target="_blank"&gt;Tarma InstallMate&lt;/a&gt; before, the you need to check this little beauty out.&amp;nbsp; It’s a fully featured installer that&amp;nbsp; have been using it in production for just under a year now and the end-user setup installer just drops out of the end of my build process – sweet!&lt;/p&gt; &lt;p&gt;There’s one thing that is very different with Tarma and all the other installers out there – Tarma doesn’t charge stupid rip-off money like all the other suppliers seem to like to do.&amp;nbsp; You can get their top-of-the-range product for under $90USD per developer.&amp;nbsp; Couple that with totally superb support, rock solid performance and a really rich feature set, Tarma’s a total winner!&lt;/p&gt; &lt;p&gt;Out of the box, Tarma has support for a number of prerequisites like .Net Framework, Access runtimes and Windows Installer.&amp;nbsp; However, it doesn’t differentiate between the Full and Client Profiles for .Net 4 – if the Client Profile is detected then it will not install the full framework and I need to get the full framework onto my user’s machine.&amp;nbsp; &lt;/p&gt; &lt;h4&gt;Detecting the Installed Framework Version&lt;/h4&gt; &lt;p&gt;To detect which version of the .Net Framework 4 has been installed, you need to check the presence of the following registry keys.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client&lt;br&gt;HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;More details on that &lt;a href="http://blogs.msdn.com/b/heaths/archive/2010/05/04/detection-keys-for-net-framework-4-0-and-visual-studio-2010.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;We can set up Tarma to do that easily, like this:&lt;/p&gt; &lt;h4&gt;Read Registry Key into a Variable&lt;/h4&gt; &lt;p&gt;Go to Symbolic Variables and add a new variable called IsFullDotnet4.&amp;nbsp; Then use Tarma’s support for &lt;a href="http://www.installmate.com/support/im7/using/symbols/index.htm" target="_blank"&gt;symbolic expressions&lt;/a&gt; to read whether the registry key exists by setting the new variable’s value to this: &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&amp;lt;$rkaccess(&amp;lt;HKLM&amp;gt;\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full)&amp;gt; &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It should now look like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_tA36DMxmDew/TMLtR3_mANI/AAAAAAAAAqA/HA5dIBbX6N0/s1600-h/SNAGHTML6641ea8%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SNAGHTML6641ea8" border="0" alt="SNAGHTML6641ea8" src="http://lh3.ggpht.com/_tA36DMxmDew/TMLtSZJ7FoI/AAAAAAAAAqE/DbC8wdID4Ks/SNAGHTML6641ea8_thumb.png?imgmax=800" width="244" height="160"&gt;&lt;/a&gt;&lt;/p&gt; &lt;h4&gt;Adjust Prerequisites Condition&lt;/h4&gt; &lt;p&gt;Go to the prerequisites section and adjust the condition to install the .Net 4 Runtime by setting the condition to this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;NOT IsFullDotnet4&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It should look something like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_tA36DMxmDew/TMPYPzZIf2I/AAAAAAAAAqQ/Up3hrBNXIx8/s1600-h/SNAGHTML7d171%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="SNAGHTML7d171" border="0" alt="SNAGHTML7d171" src="http://lh6.ggpht.com/_tA36DMxmDew/TMPYQanJRFI/AAAAAAAAAqU/_bdDN0Hqt5c/SNAGHTML7d171_thumb.png?imgmax=800" width="244" height="170"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;That’s all you need – Tarma will now upgrade .Net 4 Client Profile installations to the Full version.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-2545162448055848762?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/cx1jcFthqO4/install-full-net-4-framework-with-tarma.html</link><author>noreply@blogger.com (Sean Kearon)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_tA36DMxmDew/TMLtSZJ7FoI/AAAAAAAAAqE/DbC8wdID4Ks/s72-c/SNAGHTML6641ea8_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2010/10/install-full-net-4-framework-with-tarma.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-8529205708774705378</guid><pubDate>Mon, 04 Oct 2010 18:45:00 +0000</pubDate><atom:updated>2010-10-04T19:51:38.293+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">xpo</category><title>Replacing Strings in XPObject.SetPropertyValue with Lambdas</title><description>&lt;p&gt;I came across a post on &lt;a href="http://alfware.com.au/index.php" target="_blank"&gt;Aussie Alf&lt;/a&gt;’s blog today about removing magic strings from the persistent property setters in the &lt;a href="http://www.devexpress.com/Products/NET/ORM/" target="_blank"&gt;XPO ORM&lt;/a&gt; from &lt;a href="http://www.devexpress.com" target="_blank"&gt;DevExpress&lt;/a&gt;.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The Aussie Alf blog is written by Michael Proctor who is a member of the DevExpress community &lt;a href="http://www.dxsquad.com/" target="_blank"&gt;DXSquad&lt;/a&gt;, specialising in XPO.&amp;nbsp; The blog is a superb resource for any XPO developers and really worth reading.&amp;nbsp; Michael is also a very active member on the DevExpress forums and may well come to your help with an XPO issue there.&lt;/p&gt; &lt;p&gt;XPO uses a classic INotifyPropertyChanged pattern and passes a string of the changed property name into SetPropertyValue method.&amp;nbsp; You can see this below:&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3676b23d-2c9f-47aa-8585-86d0e06a63cc" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px; white-space: nowrap"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Customer&lt;/span&gt; : &lt;span style="color:#2b91af"&gt;XPObject&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;   &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; _number;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;   &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Number&lt;/li&gt; &lt;li&gt;   {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; _number; }&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;set&lt;/span&gt; { SetPropertyValue(&lt;span style="color:#a31515"&gt;&amp;quot;Number&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;ref&lt;/span&gt; _number, &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;); }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;   }&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;The problem with this approach is that the compiler can’t determine whether the string is correct or not, leaving you open to potential runtime errors.&amp;nbsp; Michael’s solution to this to generate a helper class that can be used in the property setter and he has a Visual Studio plugin that generates and refreshes the helper class for you based on your domain model.&amp;nbsp; &lt;/p&gt; &lt;p&gt;This is a great approach to the problem and you can read more about it on the homepage for Michael’s plugin, &lt;a href="http://code.google.com/p/dxcorecommunityplugins/wiki/XPO_EasyFields" target="_blank"&gt;XPO_EasyFields&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Michael’s &lt;a href="http://code.google.com/p/dxcorecommunityplugins/wiki/XPO_EasyFields" target="_blank"&gt;XPO_EasyFields&lt;/a&gt; plugin uses the free &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/DXCore/" target="_blank"&gt;DXCore&lt;/a&gt; Visual Studio plugin from DevExpress.&amp;nbsp; Personally, I use Resharper and don’t have DXCore installed, so I thought I would share my approach to removing the magic strings - I use a helper class and lambdas to do this.&amp;nbsp; It looks like this:&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ea84ff22-5aba-4b53-a87c-e99d5e2883e8" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px; white-space: nowrap"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Customer&lt;/span&gt; : &lt;span style="color:#2b91af"&gt;XPObject&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;   &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; _number;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;   &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Number&lt;/li&gt; &lt;li&gt;   {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; _number; }&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;set&lt;/span&gt; { SetPropertyValue(&lt;span style="color:#2b91af"&gt;Property&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af"&gt;Customer&lt;/span&gt;&amp;gt;.Name(x =&amp;gt; x.Number), &lt;span style="color:#0000ff"&gt;ref&lt;/span&gt; _number, &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;); }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;   }&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;p&gt;This relies on the use of a generic Property class and a helper method that gleans the property name from a Linq Expression.&amp;nbsp; The property class looks like this:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c33bc3cb-ae65-47e7-82a6-0f1ed5c27a99" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Property&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;   &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Name(&lt;span style="color:#2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color:#0000ff"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; expression)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;   {&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (expression == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;&amp;quot;expression&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (expression.Body &lt;span style="color:#0000ff"&gt;is&lt;/span&gt; &lt;span style="color:#2b91af"&gt;MemberExpression&lt;/span&gt;) &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; ((&lt;span style="color:#2b91af"&gt;MemberExpression&lt;/span&gt;)expression.Body).Member.Name;&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (expression.Body &lt;span style="color:#0000ff"&gt;is&lt;/span&gt; &lt;span style="color:#2b91af"&gt;UnaryExpression&lt;/span&gt; &amp;amp;&amp;amp; ((&lt;span style="color:#2b91af"&gt;UnaryExpression&lt;/span&gt;)expression.Body).Operand &lt;span style="color:#0000ff"&gt;is&lt;/span&gt; &lt;span style="color:#2b91af"&gt;MemberExpression&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;      {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; ((&lt;span style="color:#2b91af"&gt;MemberExpression&lt;/span&gt;)((&lt;span style="color:#2b91af"&gt;UnaryExpression&lt;/span&gt;)expression.Body).Operand).Member.Name;&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515"&gt;&amp;quot;Could not get property name from expression of type &amp;#39;{0}&amp;#39;&amp;quot;&lt;/span&gt;,&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                                                expression.GetType()));&lt;/li&gt; &lt;li&gt;   }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;The magic comes from translating the little lambda expression x =&amp;gt; x.Name to a string.&amp;nbsp; If I remember right, I originally based this on some code from Jeremy Miller, but there are various implementations out there.&amp;nbsp; Here’s and elegant one from &lt;a href="http://www.paulstovell.com/strong-property-names" target="_blank"&gt;Paul Stovell&lt;/a&gt; that’s focused purely on INotifyPropertyChanged.&amp;nbsp; &lt;/p&gt; &lt;p&gt;As Paul mentions in the above link, it’s worth noting that there is a performance hit when using this approach.&amp;nbsp; Michael’s approach of generating the code does not have any performance hit.&amp;nbsp; You may need to consider the performance issue if you have very high rates of properties being set.&amp;nbsp; &lt;/p&gt; &lt;p&gt;I did some simple performance tests that show a 10-15x overhead with my approach compared to Michael’s.&amp;nbsp; However, this only becomes relevant with a very large number of property sets.&amp;nbsp; For my usage scenarios the added quality benefit outweighs the performance hit, but you will need to carefully consider your scenario.&lt;/p&gt; &lt;p&gt;Lastly, to take this further, and get an even tighter syntax, I add this helper method to my persistent classes:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:38984329-ccd0-499c-bef0-dfdbec7eb12b" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px; white-space: nowrap"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; Set&amp;lt;T&amp;gt;(&lt;span style="color:#2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af"&gt;Customer&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; property, &lt;span style="color:#0000ff"&gt;ref&lt;/span&gt; T holder, T value)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;   SetPropertyValue(&lt;span style="color:#2b91af"&gt;Property&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af"&gt;Customer&lt;/span&gt;&amp;gt;.Name(property), &lt;span style="color:#0000ff"&gt;ref&lt;/span&gt; holder, value);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;This allows the setter to be even more compact:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f0f82388-fdef-48f2-ac30-c96b713ec48e" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px; white-space: nowrap"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; _number;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Number&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;   &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; _number; }&lt;/li&gt; &lt;li&gt;   &lt;span style="color:#0000ff"&gt;set&lt;/span&gt; { Set(x =&amp;gt; x.Number, &lt;span style="color:#0000ff"&gt;ref&lt;/span&gt; _number, &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;); }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;The downside is that you need the helper method in each class.&amp;nbsp; Down to taste that really, but I always go for the tighter syntax wherever possible!&amp;nbsp; &lt;/p&gt; &lt;p&gt;You can get the code from &lt;a href="https://bitbucket.org/seankearon/xpo-replace-strings-with-lambdas" target="_blank"&gt;bitbucket&lt;/a&gt; and browse the salient parts &lt;a href="https://bitbucket.org/seankearon/xpo-replace-strings-with-lambdas/src/tip/XPOWithLamdbas/Customer.cs" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-8529205708774705378?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/kY2DHdoBepg/replacing-strings-in.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>2</thr:total><feedburner:origLink>http://kearon.blogspot.com/2010/10/replacing-strings-in.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-5267946429540948021</guid><pubDate>Thu, 21 Jan 2010 23:11:00 +0000</pubDate><atom:updated>2010-04-16T16:20:28.141+01:00</atom:updated><title>Sometimes It Just Works</title><description>&lt;p&gt;Some things in life that just do what they say they will do and when this happens you get blown away.&amp;#160; &lt;/p&gt;  &lt;p&gt;VMware Workstation says it lets you use Visual Studio to debug an application that is running on a virtual machine.&amp;#160; I used this recently and was blown away by how easy it was to set up and by how amazingly useful it was.&lt;/p&gt;  &lt;p&gt;The story is that I released a new build for informal testing, but it could not be installed.&amp;#160; I installed it onto a clean XP VM (yeah, I should have done that already…) and got the error myself.&amp;#160; However, there was no error information coming back from the application as the failure was happening before the logging layer was instantiated. &lt;/p&gt;  &lt;p&gt;I was stuck.&amp;#160; I could reproduce, but had no other information to help.&amp;#160; Then I remembered that VMware Workstation had the facility to debug apps running on VMs.&amp;#160; So, I followed the instructions (yes, I was desperate enough to read the VMware help file!!) and set up a VM for remote debugging.&amp;#160; This was pretty swift to achieve and I then started a debugging session on the VM from Visual Studio.&amp;#160; &lt;/p&gt;  &lt;p&gt;Almost immediately I could see what was happening: it was my bad – I’d just forgotten to include a third-party assembly with the build.&amp;#160; My dev box was happily loading it from the GAC and so I couldn’t see I’d missed anything.&lt;/p&gt;  &lt;p&gt;VMware Workstation just did what it said it would do.&amp;#160; in doing so, it got me out of a sticky situation.&amp;#160; Also, it says it has the ability to record and replay a debugging session…maybe next time, eh?&lt;/p&gt;  &lt;p&gt;In the meantime, and whilst loving the things that go right, here’s a shot of the error from VS debugging on the VM:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_tA36DMxmDew/S1jfJHKtKGI/AAAAAAAAAYc/Hv3dbAbmMRA/s1600-h/image%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_tA36DMxmDew/S1jfJt1CgsI/AAAAAAAAAYg/f_Vqj8v-cY0/image_thumb.png?imgmax=800" width="244" height="97" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-5267946429540948021?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/Kef6azHAZ_s/sometimes-it-just-works-right.html</link><author>noreply@blogger.com (Sean Kearon)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_tA36DMxmDew/S1jfJt1CgsI/AAAAAAAAAYg/f_Vqj8v-cY0/s72-c/image_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2010/01/sometimes-it-just-works-right.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-2351309664810123365</guid><pubDate>Thu, 07 Jan 2010 19:24:00 +0000</pubDate><atom:updated>2010-01-07T19:52:43.473Z</atom:updated><title>Friendly OS Name from WMI</title><description>&lt;p&gt;When you want to find out what operating system your application is running on, &lt;font face="Courier New"&gt;System.Environment.OSVersion&lt;/font&gt; is not very readable.&amp;#160; You can get a nice friendly name using WMI like this:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;  &lt;pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GetOSName()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3:    &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; query = &amp;quot;&lt;span style="color: #8b0000"&gt;SELECT * FROM Win32_OperatingSystem&lt;/span&gt;&amp;quot;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4:    var searcher = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ManagementObjectSearcher(query);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5:    var results = from x &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; searcher.Get().OfType&amp;lt;ManagementObject&amp;gt;()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6:            select x.GetPropertyValue(&amp;quot;&lt;span style="color: #8b0000"&gt;Caption&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7:    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; results.Any() ? results.First().ToString() : &amp;quot;&lt;span style="color: #8b0000"&gt;Unknown&lt;/span&gt;&amp;quot;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This will give you something like &amp;quot;Microsoft® Windows Server® 2008 Enterprise &amp;quot;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-2351309664810123365?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/rKkpkqGEEuI/getting-friendly-os-name-from-wmi.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>1</thr:total><feedburner:origLink>http://kearon.blogspot.com/2010/01/getting-friendly-os-name-from-wmi.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-6163736458281143256</guid><pubDate>Sat, 18 Apr 2009 08:10:00 +0000</pubDate><atom:updated>2009-04-18T09:10:31.023+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">production</category><category domain="http://www.blogger.com/atom/ns#">cloud</category><title>Cloud Computing – SMD Services</title><description>&lt;p&gt;Rinat Abdullin has recently put up an interesting post about &lt;a href="http://abdullin.com/journal/2009/4/11/cloud-computing-could-windows-azure-catch-up-with-amazon.html#comments" target="_blank"&gt;cloud computing&lt;/a&gt;, along with another post as a &lt;a href="http://abdullin.com/journal/2009/4/14/why-is-cloud-computing-important-for-us.html" target="_blank"&gt;response&lt;/a&gt; to a &lt;a href="http://abdullin.com/journal/2009/4/11/cloud-computing-could-windows-azure-catch-up-with-amazon.html#comments" target="_blank"&gt;comment&lt;/a&gt; of mine.&amp;#160; Rinat pointed out the benefits cloud scenarios bring when there is a need for distributed computing resources, highlighting Amazon’s &lt;a href="http://aws.amazon.com/elasticmapreduce/" target="_blank"&gt;recent announcement&lt;/a&gt; along with Microsoft’s offerings in &lt;a href="http://research.microsoft.com/en-us/projects/Dryad/" target="_blank"&gt;that&lt;/a&gt; &lt;a href="http://research.microsoft.com/en-us/projects/dryadlinq/default.aspx" target="_blank"&gt;space&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;I agree with Rinat that distributed computing scenarios are clearly winners for cloud computing.&amp;#160; However, my view is that one of the critical success factors for the success of cloud computing will be developer adoption.&amp;#160; If you have developers using your product it will succeed (as a cloud platform), if you don’t then…well, you get it!&amp;#160; My view is that the larger organisations who already have their own infrastructure will certainly adopt cloud resources, but it will not be these organisation that will drive the adoption of cloud technologies.&amp;#160; It will be the small to medium enterprises (SME) for whom the effort to host themselves is a large compared to their overall effort to stay in business.&lt;/p&gt;  &lt;p&gt;What is going to drive SME uptake – having software that delivers business advantage.&amp;#160; How does this get to them – by developers producing it for them.&amp;#160; Making your cloud platform accessible and usable for developers will drive wider adoption.&lt;/p&gt;  &lt;p&gt;In Rinat’s &lt;a href="http://abdullin.com/journal/2009/4/14/why-is-cloud-computing-important-for-us.html" target="_blank"&gt;second&lt;/a&gt; post he mentions a scenario where if he had had a cloud platform like &lt;a href="http://www.microsoft.com/azure/default.mspx" target="_blank"&gt;Azure&lt;/a&gt; available, cost could have been saved.&amp;#160; He also outlines the basis for how cloud computing will reduce the overall costs of the adoption of a the provided in the cloud – the larger data centres selling their idle CPU cycles.&amp;#160; &lt;/p&gt;  &lt;p&gt;He then points out that there is fast evolving market for hosted developer environments where you can easily and cheaply access version control, wiki, issue tracker services, etc.&amp;#160; In an earlier post I mentioned one such provider, &lt;a href="http://kearon.blogspot.com/2008/06/praise-subversion-hosting-at-wushnet.html" target="_blank"&gt;WUSH&lt;/a&gt;, with whom I have had a positive experience throughout the last year in the smaller scale development work I do out of normal working hours.&amp;#160; &lt;/p&gt;  &lt;p&gt;It is this area – developer services – that I see as the key to making cloud computing ubiquitous.&amp;#160; If you can provide developers with full-lifecycle support from your platform they will come in their droves.&amp;#160; By full lifecycle, I mean support for planning, production, test and live all in an integrated set of cloud services.&lt;/p&gt;  &lt;p&gt;As mentioned, there we see some support for planning and some aspects of production already out there (search for “&lt;a href="http://www.google.co.uk/search?rlz=1C1CHMR_en-GBGB306GB306&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=hosted+subversion" target="_blank"&gt;hosted subversion&lt;/a&gt;”, take a look at &lt;a href="http://www.google.co.uk/search?rlz=1C1CHMR_en-GBGB306GB306&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=hosted+subversion" target="_blank"&gt;Scrumy&lt;/a&gt; or &lt;a href="http://www.manymoon.com" target="_blank"&gt;Manymoon&lt;/a&gt;, etc.), and you can but cost efficient test and live&amp;#160; environments (by renting your own server).&amp;#160; But to get other aspects running, like a build or &lt;a href="http://www.martinfowler.com/articles/continuousIntegration.html" target="_blank"&gt;CI&lt;/a&gt; environment, involves setting it up yourself on a server you have rented yourself.&amp;#160; However, doing that would not be using &lt;a href="http://en.wikipedia.org/wiki/Software_as_a_service" target="_blank"&gt;SaaS&lt;/a&gt; beyond having a server hosted in the cloud.&amp;#160; Unfortunately, I know of no decently priced build service that for commercial projects.&lt;/p&gt;  &lt;p&gt;What do I want to see?&amp;#160; In the short term, I’m missing a &lt;strike&gt;sensibly&lt;/strike&gt; cheaply priced build services for commercial projects (see James Kovac’s recent &lt;a href="http://www.jameskovacs.com/blog/AnnouncingTeamCityCodeBettercom.aspx" target="_blank"&gt;announcement&lt;/a&gt; of their new &lt;a href="http://www.jetbrains.com/teamcity/" target="_blank"&gt;Team City&lt;/a&gt; service for OS projects).&amp;#160; In the longer term I want to be able to have a fully hosted CI environment that prices me by disk and CPU usage.&amp;#160; &lt;/p&gt;  &lt;p&gt;The ultimate goal: Microsoft to host &lt;a href="http://msdn.microsoft.com/en-us/teamsystem/dd408382.aspx" target="_blank"&gt;TFS&lt;/a&gt; and reduce the cost of adoption for SMDs (small to medium developers :) ) to the &lt;a href="http://msdn.microsoft.com/en-us/teamsystem/default.aspx" target="_blank"&gt;Team System&lt;/a&gt; versions of Visual Studio.&lt;/p&gt;  &lt;p&gt;In the meantime, will I be using the current set of cloud services?&amp;#160; Absolutely, both in my production processes as an SMD and for services that my clients will use.&amp;#160; And, I am doing this for the the reasons &lt;a href="http://abdullin.com/" target="_blank"&gt;Rinat&lt;/a&gt; has outlined!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-6163736458281143256?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/lCn8LXnqowc/cloud-computing-smd-services.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>2</thr:total><feedburner:origLink>http://kearon.blogspot.com/2009/04/cloud-computing-smd-services.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-4973450791296211341</guid><pubDate>Mon, 15 Dec 2008 20:15:00 +0000</pubDate><atom:updated>2009-04-18T08:01:57.061+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">visualstudio</category><title>Double Click to Open Visual Studio Solutions in Vista/2008</title><description>&lt;p&gt;For a while I have been running Visual Studio under Vista (x32) and now I’m using &lt;a href="http://www.win2008workstation.com/wordpress/" target="_blank"&gt;Workstation 2008&lt;/a&gt; (very happily too!).&amp;#160;&amp;#160; I have UAC on, but have a policy setting to automatically elevate without showing a prompt.&amp;#160; (I absolutely can’t live with the dialogs…see &lt;a href="http://kearon.blogspot.com/2008/06/uac-time-is-marked.html" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://kearon.blogspot.com/2008/06/uac-peace-at-last.html" target="_blank"&gt;here&lt;/a&gt; for more info).&lt;/p&gt;  &lt;p&gt;I have also Visual Studio set to run as administrator, and that’s where the problem starts: I have not been able to open solution files by double clicking them.&amp;#160; &lt;/p&gt;  &lt;p&gt;I am very grateful to “Sajeev Prasad / Arun Arcot” response to &lt;a href="http://www.pluralsight.com/community/blogs/matt/archive/2007/05/21/47446.aspx" target="_blank"&gt;this post&lt;/a&gt; for the solution.&lt;/p&gt;  &lt;p&gt;Basically, set both IDE and the loader (%programfiles%\Common Files\Microsoft Shared\MSEnv\VSLauncher.exe) to run as administrator and you can then double click to open solutions.&lt;/p&gt;  &lt;p&gt;Thanks Sajeev and Arun!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-4973450791296211341?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/zE4dBkXII8s/double-click-to-open-visual-studio.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/12/double-click-to-open-visual-studio.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-5852325940942319358</guid><pubDate>Mon, 15 Dec 2008 01:17:00 +0000</pubDate><atom:updated>2008-12-15T01:20:47.520Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">resharper</category><title>ReSharper Plugins</title><description>&lt;p&gt;I’ve been using ReSharper since it’s first EAP release (late 2003 or early 2004, if I am right) and quite simply would not want to code without it. &lt;/p&gt;  &lt;p&gt;ReSharper is a platform that can be easily extended and it is worth noting that there are a number of excellent plugins available that to make your ReSharper experience even better. &lt;/p&gt;  &lt;p&gt;I mentioned &lt;a href="http://kearon.blogspot.com/2008/12/joyful-reflections-resharper-scout.html" target="_blank"&gt;Scout&lt;/a&gt; in an earlier post, but there are plugins for NHibernate, Gallio, xUnit and also for stuff like helping extract resources for internationalisation. &lt;/p&gt;  &lt;p&gt;Check &lt;a href="http://www.jetbrains.com/resharper/plugins/" target="_blank"&gt;here&lt;/a&gt; for more details.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-5852325940942319358?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/FBDiK49AKu4/resharper-plugins.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/12/resharper-plugins.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-4280979360067297038</guid><pubDate>Mon, 15 Dec 2008 00:44:00 +0000</pubDate><atom:updated>2008-12-15T00:49:53.422Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">xml</category><title>XML Editor - Liquid XML Studio</title><description>&lt;p&gt;I’ve just started using a great XML editor: &lt;a href="http://www.liquid-technologies.com/Product_XmlStudio.aspx" target="_blank"&gt;Liquid XML Studio&lt;/a&gt;.&amp;#160; I used it when creating some XSDs the other day.&amp;#160; It’s really easy to use, and has a great graphical interface too.&amp;#160; &lt;/p&gt;  &lt;p&gt;The thing I really really like is the feature to generate an instance of the schema.&amp;#160; The only other tool I’m aware of that does this is the BizTalk schema editor – but that’s a bit more of a heavyweight tool than I usually need!&lt;/p&gt;  &lt;p&gt;It also has Visual Studio integration (with the visual editor), XPath expression builder, documentation generation and a web service browser.&amp;#160; It’s not cheap, but there is a free feature limited &lt;a href="http://www.liquid-technologies.com/Product_XmlStudio_Features.aspx" target="_blank"&gt;Community Edition&lt;/a&gt;.&amp;#160; There’s also the high end &lt;a href="http://www.liquid-technologies.com/Product_XmlDataBinding.aspx" target="_blank"&gt;Developer Edition&lt;/a&gt; that adds a load of muscle for people working with more complex schemas, such as the &lt;a href="http://www.oasis-open.org/home/index.php" target="_blank"&gt;OASIS&lt;/a&gt; schemas.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-4280979360067297038?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/C_dAYV08pMg/xml-editor-liquid-xml-studio.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/12/xml-editor-liquid-xml-studio.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-6957976025569437110</guid><pubDate>Mon, 15 Dec 2008 00:21:00 +0000</pubDate><atom:updated>2008-12-15T00:28:01.495Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">resharper</category><title>Joyful Reflections - ReSharper Scout</title><description>&lt;p&gt;I’ve just found an excellent &lt;a href="http://www.jetbrains.com/resharper/" target="_blank"&gt;ReSharper&lt;/a&gt; plugin called &lt;a href="http://code.google.com/p/scoutplugin/" target="_blank"&gt;Scout&lt;/a&gt;.&amp;#160; This lovely little beast will open &lt;a href="http://www.red-gate.com/products/reflector/" target="_blank"&gt;Reflector&lt;/a&gt; when you choose Go to Declaration.&amp;#160; The thing I really love is that Scout also takes care of loading the appropriate assembly in Reflector.&amp;#160; I previously had to load the assembly in Reflector before I could browse it, which took time.&amp;#160; Scout makes this process seamless.&lt;/p&gt;  &lt;p&gt;All you have to do is right click and select Go to Declaration:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_tA36DMxmDew/SUWjHMTj8nI/AAAAAAAAAWE/1KpRuQwUZ_Q/s1600-h/changed%5B2%5D.png"&gt;&lt;img title="Selecting the &amp;quot;Go to Declaration&amp;quot; menu item" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="217" alt="Selecting the &amp;quot;Go to Declaration&amp;quot; menu item" src="http://lh3.ggpht.com/_tA36DMxmDew/SUWjH1weuJI/AAAAAAAAAWI/yDjHqqGQmsM/changed_thumb.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Then you get taken to the item in Reflector and the correct assembly is loaded:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_tA36DMxmDew/SUWjJJXO-jI/AAAAAAAAAWM/KpG74TzphhM/s1600-h/reflector%5B2%5D.png"&gt;&lt;img title="reflector" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="138" alt="reflector" src="http://lh5.ggpht.com/_tA36DMxmDew/SUWjJhCZRyI/AAAAAAAAAWQ/pg_MrCMQzhY/reflector_thumb.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Scout will also take you to the &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/10/03/releasing-the-source-code-for-the-net-framework-libraries.aspx" target="_blank"&gt;Dotnet source code&lt;/a&gt; – but I haven’t got around to that yet!&amp;#160; You can find lots of other ReSharper plugin goodness &lt;a href="http://www.jetbrains.com/resharper/plugins/" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-6957976025569437110?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/vlBifIPnHaA/joyful-reflections-resharper-scout.html</link><author>noreply@blogger.com (Sean Kearon)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_tA36DMxmDew/SUWjH1weuJI/AAAAAAAAAWI/yDjHqqGQmsM/s72-c/changed_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/12/joyful-reflections-resharper-scout.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-6512962686300383946</guid><pubDate>Sat, 29 Nov 2008 07:12:00 +0000</pubDate><atom:updated>2008-11-30T16:20:24.284Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">xpo</category><category domain="http://www.blogger.com/atom/ns#">devexpress</category><title>Update on XPO and One-Way Associations</title><description>&lt;a href="http://3.bp.blogspot.com/_tA36DMxmDew/STDwgIygT9I/AAAAAAAAAV4/sSkhWxIWjTU/s1600-h/stop.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_tA36DMxmDew/STDwgIygT9I/AAAAAAAAAV4/sSkhWxIWjTU/s200/stop.gif" /&gt;&lt;/a&gt;I stated in a &lt;a href="http://kearon.blogspot.com/2008/11/express-persistent-objects-xpo-to.html"&gt;previous post&lt;/a&gt; that XPO would be supporting one-way multi associations.&amp;nbsp; Unfortunately, this is now not the case.&amp;nbsp; At the time I wrote the previous post, &lt;a href="http://www.devexpress.com/"&gt;Developer Express&lt;/a&gt; had marked my request as accepted, but have now changed that to rejected.&lt;br /&gt;
&lt;br /&gt;
The guys at Developer Express support say that having a two-way association in your object model is fundamental to XPO multiple associations and, as my request was only to simplify code, the feature is now not to be implemented.&amp;nbsp; The bottom line from them was:&lt;br /&gt;
&lt;blockquote&gt;"To sum it up, we think that the current design of one-to-many associations in XPO is reliable and transparent. We are not going to change it, unless we have strong arguments for doing so."&lt;/blockquote&gt;Well, although it's a shame that it's not going to be implemented, you can't argue than that!&lt;br /&gt;
&lt;br /&gt;
You can find the request thread &lt;a href="http://www.devexpress.com/Support/Center/p/S130253.aspx"&gt;here&lt;/a&gt; (but may need to register).&amp;nbsp; If you still want to keep your XPO code clean, you can use some IL enhancement with PostSharp - details &lt;a href="http://kearon.blogspot.com/2008/10/using-postsharp-to-allow-one-way.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-6512962686300383946?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/-h3-J4h5Xew/update-on-xpo-and-one-way-associations.html</link><author>noreply@blogger.com (Sean Kearon)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_tA36DMxmDew/STDwgIygT9I/AAAAAAAAAV4/sSkhWxIWjTU/s72-c/stop.gif" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/11/update-on-xpo-and-one-way-associations.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-8708785261562992144</guid><pubDate>Thu, 20 Nov 2008 08:09:00 +0000</pubDate><atom:updated>2008-11-20T10:10:17.816Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">xpo</category><category domain="http://www.blogger.com/atom/ns#">devexpress</category><title>Why Support One-Way Multiple Associations?</title><description>&lt;a href="http://1.bp.blogspot.com/_tA36DMxmDew/SSUuvR3cl4I/AAAAAAAAAVw/Qb_ZJhQ6TvM/s1600-h/oneway.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 2em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_tA36DMxmDew/SSUuvR3cl4I/AAAAAAAAAVw/Qb_ZJhQ6TvM/s320/oneway.jpg" /&gt;&lt;/a&gt;This post is to answer a question from the Developer Express support team as to why I have requested that XPO support one-way multiple associations.  The primary reason for my request is to reduce code noise.  When you do not want a reverse association in your model, then you should not be forced to put it in.  Using the example from my previous post, if all you need is a one-way association you should be able to write:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;p&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ublic class Customer : XPObject&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public XPCollection&lt;order&gt;&lt;/order&gt;&lt;order&gt;&lt;/order&gt;&lt;order&gt; Orders { get; }&lt;/order&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public class Order : XPObject&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;
However, as XPO currently &lt;i&gt;requires&lt;/i&gt; you to implement a two-way association in your object model.  You have to write something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public class Customer : XPObject&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Association("CustomerOrders")]&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public XPCollection&lt;order&gt;&lt;order&gt;&lt;/order&gt;&lt;/order&gt;&lt;order&gt;&lt;/order&gt;&lt;order&gt; Orders { get; }&lt;/order&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public class Order : XPObject&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Association("CustomerOrders")]&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Customer Customer;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;
XPO has made me:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Add an attribute to my association property.&lt;/li&gt;
&lt;li&gt;Give that attribute a unique string to identify the association.&lt;/li&gt;
&lt;li&gt;Add a new property to my linked type.&lt;/li&gt;
&lt;li&gt;Add an attribute to this new property.&lt;/li&gt;
&lt;li&gt;Give this attribute the same string so as to identify it is part of the association.&lt;/li&gt;
&lt;/ul&gt;I have no problem with doing that &lt;i&gt;when I need&lt;/i&gt; the association to be two-way.  Indeed, XPO does some good things for me when I do need this: it maintains the linked states of the linked instances, which is a great help!  In other words, when the &lt;span style="font-family: &amp;quot;;"&gt;Association&lt;/span&gt; attribute is used as above, adding an order to a customer's orders will automatically set the order's customer; removing the customer from the order's customer property will remove the order from the customer's orders property.  Very nice to have and certainly removes code that I would need to write. &lt;br /&gt;
&lt;br /&gt;
You are probably looking at the above example and thinking that you would naturally have an association from order to customer, and I would agree.  However, let's say that you have a requirement to show the recently ordered products against the customer.  One way of implementing this would be:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class Customer : XPObject&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; public XPCollection&lt;order&gt;&lt;/order&gt;&lt;order&gt; RecentProducts&lt;product&gt; { get; }&lt;/product&gt;&lt;/order&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;
In this circumstance, I would not want to have to implement a reverse association:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;    public class Customer : XPObject&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp;       [Association("CustomerRecentProducts")]&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp;          public XPCollection&lt;order&gt;&lt;/order&gt;&lt;order&gt; RecentProducts&lt;product&gt; { get; }&lt;/product&gt;&lt;/order&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;    }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;
&amp;nbsp; public class Product : XPObject&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;    {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp;       [Association("CustomerRecentProducts")]&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp;          public XPCollection&lt;order&gt;&lt;/order&gt;&lt;order&gt; Customers&lt;customer&gt; { get; }&lt;/customer&gt;&lt;/order&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;    }&lt;/div&gt;&lt;br /&gt;
In this case I would consider the reverse association to be worse than code noise - it is structurally worng and simply should not be there!  Maybe we should be suspicious of the &lt;span style="font-family: &amp;quot;;"&gt;Customer.RecentProduct&lt;/span&gt;s association in the first place too, but that's another story!&lt;span style="font-family: &amp;quot;;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Another time when being forced to implement a reverse association is when the two classes are in different assemblies.  I would have to move the classes to avoind a circular reference.  Maybe I should ask for XPO to support &lt;i&gt;persistence by interface&lt;/i&gt; too...&lt;br /&gt;
&lt;span style="font-family: &amp;quot;;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-8708785261562992144?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/UXuS11J_GV0/why-support-one-way-multiple.html</link><author>noreply@blogger.com (Sean Kearon)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_tA36DMxmDew/SSUuvR3cl4I/AAAAAAAAAVw/Qb_ZJhQ6TvM/s72-c/oneway.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/11/why-support-one-way-multiple.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-153269649007200985</guid><pubDate>Mon, 10 Nov 2008 07:49:00 +0000</pubDate><atom:updated>2008-12-15T01:04:38.217Z</atom:updated><title>Express Persistent Objects (XPO) to Support One-Way Multiple Associations</title><description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update December 2008:&lt;/strong&gt; this has changed and is no longer to be supported.&amp;#160; See &lt;/em&gt;&lt;a href="http://kearon.blogspot.com/2008/11/update-on-xpo-and-one-way-associations.html" target="_blank"&gt;&lt;em&gt;here&lt;/em&gt;&lt;/a&gt;&lt;em&gt; for details.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I'm happy to say that Developer Express have now accepted my request to support one-way multiple associations in XPO.&amp;#160; See &lt;a href="http://www.devexpress.com/Support/Center/p/S130253.aspx"&gt;here&lt;/a&gt; for more details.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-153269649007200985?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/t8kD1pserKA/express-persistent-objects-xpo-to.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/11/express-persistent-objects-xpo-to.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-1365474236444176473</guid><pubDate>Fri, 31 Oct 2008 00:04:00 +0000</pubDate><atom:updated>2008-11-12T20:29:25.751Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">xpo</category><category domain="http://www.blogger.com/atom/ns#">devexpress</category><category domain="http://www.blogger.com/atom/ns#">postsharp</category><title>Using PostSharp to Allow One-Way Multiple Associations in XPO</title><description>The &lt;a href="http://www.devexpress.com/Products/NET/ORM/"&gt;Express Persistent Objects&lt;/a&gt; (XPO) ORM from &lt;a href="http://www.devexpress.com/"&gt;Developer Express&lt;/a&gt; does not support one way associations with multiplicity greater than one.&amp;nbsp; Each collection association from a type must have a corresponding reverse association from the linked type.&amp;nbsp; The reverse link can be either a unary or a collection (making either a one-many or many-many association, respectively).&lt;br /&gt;
&lt;br /&gt;
I put in a request for one-way multi associations &lt;a href="http://www.devexpress.com/Support/Center/p/S130253.aspx"&gt;here&lt;/a&gt; (you may need to register to view).&amp;nbsp; The response I got back was basically that implementing one-way multi associations would "break existing functionality and this approach contradicts with the XPO concepts".&amp;nbsp; I think that this is a shame, but there you go.&lt;br /&gt;
&lt;br /&gt;
So, given that I want this feature, I'm going to find the middle ground: let's have one-way associations, but use &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt; to implement the extra code to keep XPO happy.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;The Problem:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
I want to be able to write this as valid XPO code:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public class Customer : XPObject&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public XPCollection&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;order&gt;&lt;/order&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;order&gt; Orders { get; }&lt;/order&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public class Order : XPObject&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;But XPO wants me to add the other end of the link to Order and to also add associated attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public class Customer : XPObject&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Association("CustomerOrders")]&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public XPCollection&lt;order&gt;&lt;/order&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;order&gt;&lt;/order&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;order&gt; Orders { get; }&lt;/order&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public class Order : XPObject&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Association("CustomerOrders")]&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Customer Customer;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
So, for my one-way association there must be another property or field on the linked class as well as marking each participting property(or field with the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Association&lt;/span&gt; attribute. Not a huge amount of extra code and not an unreasonable amount either!&lt;br /&gt;
&lt;br /&gt;
(Also, it's worth noting here that I am again using &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt; to let me use automatic properties with XPO here - there is a little more required for normal XPO code.&amp;nbsp; See my &lt;a href="http://kearon.blogspot.com/2008/10/using-c-automatic-properties-with-xpo.html"&gt;previous&lt;/a&gt; &lt;a href="http://kearon.blogspot.com/2008/10/using-c-automatic-properties-with-xpo_27.html"&gt;posts&lt;/a&gt; for more details on how this is done.) &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;A Solution:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
We're going to use &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt; to generate the reverse link for us and to add the associations that XPO requires.&amp;nbsp; Basically, I am going to write code as in the first section above and get PostSharp to enhance it at compile time so that it is actually like the second section.&amp;nbsp; Specifically, I'm going to use PostSharp to:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Add a public field to a class.&lt;/li&gt;
&lt;li&gt;Add an attribute to this new field.&lt;/li&gt;
&lt;li&gt;Add an attribute to an existing property.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Some Caveats:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
If you care about the reverse link, you will want to implement it yourself as is usual in XPO.&amp;nbsp; The way we are doing it here means that the generated reverse link will not be visible at design time from inside of its own assembly (but it will be from outside the assembly).&lt;br /&gt;
&lt;br /&gt;
Also, the current implementation is not compatible with the Compact Framework or Silverlight.&amp;nbsp; For this you will need to use the upcoming version 1.5 of PostSharp - more details &lt;a href="http://www.postsharp.org/blog/2008/10/what-really-changed-between-10-and-15-1-targeting-silverlight-and-the-compact-framework/"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Approach&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;As you will see from the PostSharp web site, PostSharp is made up of &lt;a href="http://www.postsharp.org/about/features/"&gt;two main sections&lt;/a&gt; - PostSharp.Core and PostSharp.Laos.&amp;nbsp; PostSharp.Laos is a plugin on top of PostSharp.Core that simplifies a lot of the common tasks in &lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming"&gt;AOP&lt;/a&gt;.&amp;nbsp; PostSharp.Core is the main engine that enchances your code at compile time.&amp;nbsp; It is both powerful and deep, and I am certainly not an expert in its use!&amp;nbsp; However, despite all the power and depth, it is also fairly accesssible.&lt;br /&gt;
&lt;br /&gt;
The PostSharp website uses the lovely term "&lt;b style="font-weight: normal;"&gt;Pay-As-You-Use Complexity&lt;/b&gt;" for PostSharp - you can acheive pretty much anything you want and the common tasks are made fairly simple (by PostSharp.Laos), while other tasks may require you to gain some more knowledge of the inner workings of PostSharp (meaning PostSharp.Core). In my &lt;a href="http://kearon.blogspot.com/2008/10/using-c-automatic-properties-with-xpo.html"&gt;previous&lt;/a&gt; &lt;a href="http://kearon.blogspot.com/2008/10/using-c-automatic-properties-with-xpo_27.html"&gt;articles&lt;/a&gt; about PostSharp, we used PostSharp.Laos, for this task we are going to use PostSharp.Core.&lt;br /&gt;
&lt;br /&gt;
In this article, I'm going to show how to add fields and attributes to classes using PostSharp.Core.&amp;nbsp; I was inspired by &lt;a href="http://www.sitechno.com/Blog/default.aspx"&gt;Ruurd Boeke's&lt;/a&gt; articles, which you can find &lt;a href="http://www.sitechno.com/Blog/IntroducingEntityFrameworkContribEasyIPocoImplementationV01.aspx"&gt;here&lt;/a&gt;.&amp;nbsp; Ruurd uses PostSharp to enchance POCO classes for the Entity Framework use and goes a lot further with PostSharp than I do here.&amp;nbsp; I highly recommend reading Ruurd's articles for more detailed information.&lt;br /&gt;
&lt;br /&gt;
Let's now have a look what we need to do to get PostSharp to do what we want.&amp;nbsp; I'm going to break this down into three sections:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=2285278671879033267&amp;amp;postID=1365474236444176473#stage1"&gt;Stage 1 - Attach Aspects&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=2285278671879033267&amp;amp;postID=1365474236444176473#stage2"&gt;Stage 2 - Create a Weaver Task&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=2285278671879033267&amp;amp;postID=1365474236444176473#stage1"&gt;Stage 3 - Do the Weaving&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://draft.blogger.com/post-edit.g?blogID=2285278671879033267&amp;amp;postID=1365474236444176473" name="stage1"&gt;&lt;/a&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Stage 1&lt;/b&gt; - &lt;b&gt;Attach Aspects&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
The first step is to create a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;CompoundAspect&lt;/span&gt; as we have done before.&amp;nbsp; The job of this attribute is going to be to add other PostSharp aspects to our classes.&amp;nbsp; The other aspects will then be picked up and used by PostSharp.Core.&amp;nbsp; The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ProvideAspects&lt;/span&gt; method looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;1 public override void ProvideAspects(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; object element,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LaosReflectionAspectCollection collection)&lt;br /&gt;
2 {&lt;br /&gt;
3 &amp;nbsp; &amp;nbsp; var targetType = (Type) element;&lt;br /&gt;
4&amp;nbsp; &amp;nbsp; &amp;nbsp; foreach (var property in targetType.UnderlyingSystemType&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .GetProperties()&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Where(info =&amp;gt; info.DeclaredIn(targetType) &amp;amp;&amp;amp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; info.IsOneWayAssociation()))&lt;br /&gt;
5&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
6 &amp;nbsp; &amp;nbsp;&amp;nbsp; var fieldName = GetGeneratedFieldName(property);&lt;br /&gt;
7&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; collection.AddAspect(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; property.GetCollectionTargetType(),&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new OtherEndFieldSubAspect(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; targetType.FullName,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; fieldName,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; fieldName));&lt;br /&gt;
8&lt;br /&gt;
9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; collection.AddAspect(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; targetType,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; new AssociationAttributeSubAspect(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; property.Name,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fieldName));&lt;br /&gt;
10&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;11 }&lt;/div&gt;&lt;br /&gt;
In line 4 we use a bit of LINQ to iterate through the properties of our target type that we are interested in enchancing and then in line 6 we call a helper method to get the name of the field we want to generate.&amp;nbsp; In lines 7 and 9 we add the aspects.&amp;nbsp; In line 7 we add an aspect to the type at the other end of our collection and pass it the name of the type of the field we want to add, along with a field name and a string to be passed to the association attribute that we will add later.&amp;nbsp; Note that we are using an extension method helper (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GetCollectionTargetType&lt;/span&gt;) to get the type at the other end, although this is nothing more than normal reflection code.&amp;nbsp; Next, in line 9, we add another aspect to the type that is declaring the collection property, passing it the name of the property that will be enchaned and a string that we will pass to the attribute that we add to the property.&lt;br /&gt;
&lt;br /&gt;
So, we have used PostSharp.Laos to add aspects to our classes.&amp;nbsp; These aspects contain some information that we will use later.&amp;nbsp; In fact, as you can see below, the aspects that we have added contain little else other than the information we want to use later.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class OtherEndFieldSubAspect : ILaosTypeLevelAspect&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public OtherEndFieldSubAspect(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string fieldTypeName,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string fieldName,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string associationName)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldTypeName = fieldTypeName;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldName = fieldName;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AssociationName = associationName;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public void CompileTimeInitialize(Type type) {&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public bool CompileTimeValidate(Type type)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public void RuntimeInitialize(Type type) { }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public int AspectPriority&lt;br /&gt;
&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return int.MinValue; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public string AssociationName { get; set; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public string FieldName { get; set; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public string FieldTypeName { get; set; }&lt;br /&gt;
}&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class AssociationAttributeSubAspect : ILaosTypeLevelAspect&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public AssociationAttributeSubAspect(&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string propertyName, string associationName)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PropertyName = propertyName;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AssociationName = associationName;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public void CompileTimeInitialize(Type type)&lt;/span&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public bool CompileTimeValidate(Type type)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public void RuntimeInitialize(Type type) &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public int AspectPriority&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return int.MinValue; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public string AssociationName { get; set; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public string FieldName { get; set; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; public string PropertyName { get; set; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Note that these tasks implement &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ILaosTypeLevelAspect&lt;/span&gt; as we are applying the aspects to types.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://draft.blogger.com/post-edit.g?blogID=2285278671879033267&amp;amp;postID=1365474236444176473" name="stage2"&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Stage 2 - Create a Weaver Task&lt;/span&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
PostSharp's weaver is what we are going to use to create the new field and add the custom attributes.&amp;nbsp; The public parts of PostSharp are LGPL and can therefore be freely distributed under any license you choose, whereas PostSharp.Core is licensed under the &lt;a href="http://en.wikipedia.org/wiki/Copyleft"&gt;copyleft&lt;/a&gt; GPL, and so you cannot distribute PostSharp.Core in another GPL application.&amp;nbsp; So, if we want to use this commercially, the weaver needs to be split out from the main distribution if the software is going to be used commercially.&amp;nbsp; This is not a problem as the enhancements happen at compile time and the designer of PostSharp, &lt;a href="http://gael.fraiteur.net/"&gt;Gael Fratieur&lt;/a&gt; has made this easy for us to seperate PostSharp.Core!&amp;nbsp; The basis of this is to use PostSharp "tasks" to tell PostSharp.Core what to do at compile time.&amp;nbsp; A task has a name and points to a weaver implementation that will handle the task.&amp;nbsp; You configure the tasks in XML as below:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;plugin xmlns="http://schemas.postsharp.org/1.0/configuration"&gt;&lt;/plugin&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &lt;tasktype name="WeaveTwoWayAssociations"&gt;&lt;/tasktype&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Implementation="&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Weaver.WeaverFactory, Weaver&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;"&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The task called &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WeaveTwoWayAssociations&lt;/span&gt; is handled by the type &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Weaver.WeaverFactory &lt;/span&gt;which can be found in the assembly called Weaver.&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&amp;nbsp; This file and the rest of the weaver code sits in a seperate project.&amp;nbsp; Other projects find this by adding the weaver to the search path and adding an assembly level attribute to the project where we defined our &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AssociationAttributeSubAspect &lt;/span&gt;and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;OtherEndFieldSubAspect&lt;/span&gt;  aspects.&amp;nbsp; We also add the weaver project's output folder to each referencing projects search path (inside project | properties).&amp;nbsp; The assembly attribute looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[assembly: PostSharp.Extensibility.ReferencingAssembliesRequirePostSharp("WeaveTwoWayAssociations", "Weaver")]&lt;br /&gt;
[assembly: InternalsVisibleTo("Weaver")]&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;Note that the task name and the assembly in which it can be found are indicated.&amp;nbsp; We also have to allow the weaver to reference our internals!&amp;nbsp; Also, note that PostSharp has another, more portable, mechanism to tell reference the weaver files, as described in &lt;a href="http://www.sitechno.com/Blog/PostcompilingForEntityFrameworkPartV.aspx"&gt;Ruurd's article&lt;/a&gt;.&amp;nbsp; For whatever reason, I could not get this to work and so have just added the reference path.&amp;nbsp; You will need to change this path on your machine or you will get compile errors about not being able to find a plugin:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_tA36DMxmDew/SQ2nDqb7hzI/AAAAAAAAAVY/eeYFF2qAvJI/s1600-h/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_tA36DMxmDew/SQ2nDqb7hzI/AAAAAAAAAVY/iWOJNoTI98c/s400-R/Untitled.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: left;"&gt;Okay, so we've now got a task setup to let PostSharp's weaver loose on our aspects. &amp;nbsp; We now just need to define what the weaver needs to do.&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://draft.blogger.com/post-edit.g?blogID=2285278671879033267&amp;amp;postID=1365474236444176473" name="stage3"&gt;&lt;/a&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Stage 3 - Do the Weaving&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
In our configuration we said that the task called &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WeaveTwoWayAssociations&lt;/span&gt; was handled by the class &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Weaver.WeaverFactory.&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WeaverFactory &lt;/span&gt;implements &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ILaosAspectWeaverFactory &lt;/span&gt;and looks like this: &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class WeaverFactory : Task, ILaosAspectWeaverFactory&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public LaosAspectWeaver CreateAspectWeaver(ILaosAspect aspect)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (aspect is OtherEndFieldSubAspect)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;addField&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; = (OtherEndFieldSubAspect)aspect;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new AddFieldWeaver(&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;addField&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.FieldTypeName,&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;addField&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.FieldName,&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;addField&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.AssociationName);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (aspect is AssociationAttributeSubAspect)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;addAttribute&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; = (AssociationAttributeSubAspect)aspect;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new PropertyAttributeWeaver(&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; addAttribute&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.PropertyName,&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;addAttribute&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.AssociationName);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Ttrue to its name, the factory is responsible for providing instances of types that can do some work for us.&amp;nbsp; Note that the factory is looking for the aspects that we added in stage 1.&amp;nbsp; When a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;OtherEndFieldSubAspect&lt;/span&gt; is encountered, an instance of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AddFieldWeaver &lt;/span&gt;is created and returned to PostSharp.&amp;nbsp; When a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AssociationAttributeSubAspect &lt;/span&gt;is encountered, an instance of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PropertyAttributeWeaver &lt;/span&gt;is created and returned to PostSharp. &lt;br /&gt;
&lt;br /&gt;
So, as indicated above, the work of adding a field is done by the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AddFieldWeaver&lt;/span&gt; class.&amp;nbsp; You might be expecting this class to be pretty complex and have lots of IL in it.&amp;nbsp; If you are, you're in for a surprise as it's actually really clean and straight forward: &lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class AddFieldWeaver : TypeLevelAspectWeaver&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public AddFieldWeaver(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string fieldTypeName, string fieldName,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string associationName)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldTypeName = fieldTypeName;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldName = fieldName;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AssociationName = associationName;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; private ITypeSignature fieldType;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public override void Implement()&lt;br /&gt;
&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var newField =&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new FieldDefDeclaration&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name = FieldName, &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Attributes = FieldAttributes.Public, &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldType = FieldType &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((TypeDefDeclaration) TargetType).Fields.Add(newField);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var attribute = Utils.CreateAssociationAttribute(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Task.Project.Module, AssociationName);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newField.CustomAttributes.Add(attribute);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public string AssociationName { get; set; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public ITypeSignature FieldType&lt;br /&gt;
&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (fieldType == null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fieldType =&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Task.Project.Module.FindType(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldTypeName,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BindingOptions.Default);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return fieldType;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; public string FieldTypeName { get; set; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp; private string FieldName { get; set; }&lt;br /&gt;
}&lt;/div&gt;&lt;br /&gt;
The waever is an implementation of the PostSharp TypeLevelAspectWeaver and its &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Implement&lt;/span&gt; method is where the new field is created.&amp;nbsp; This method simply creates a new FieldDefDeclaration that represents the new field, sets its name, defines its visibility (by setting the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Attributes&lt;/span&gt; property) and sets it's type.&amp;nbsp; The type is derived from a helper property called &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;FieldType &lt;/span&gt;which uses PostSharp's built in Task.Project.Module to find the type of the name that was specified when we created the attribute in stage 1. &lt;br /&gt;
Then, the new field is simply added to the target type's fields collection.&amp;nbsp; Next, a helper method is called to create an instance of the custom attribute we want to add and is added to teh new field's custom attributes collection.&amp;nbsp; That's all there is to it!!!&lt;br /&gt;
&lt;br /&gt;
PostSharp has been widely praised for having a very clean and well designed API.&amp;nbsp; After doing this I can really see why it is so well thought of - we have been sheltered from all the horrid IL generation that is usually associated with this sort of task.&amp;nbsp; Quite simply, PostSharp totally rocks and Gael Fraiteur has done an amazing job!&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;The Results&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
So, what do we have now?&amp;nbsp; If you remeber, we started with types that looked like this:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[AllowXpoOneWayAssociations]&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public class Customer : XPObject&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public XPCollection&lt;order&gt; Orders&lt;/order&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;order&gt;&lt;/order&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;order&gt; { get; }&lt;/order&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; [AllowXpoOneWayAssociations]&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public class Order : XPObject&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If we now look at the assembly in &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt;, we can see that a public field along with an custom attribute has been added to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Order &lt;/span&gt;and an attribute has been added to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Customer&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_tA36DMxmDew/SQ2t4oujjjI/AAAAAAAAAVg/wXLgmYzJlXY/s1600-h/code.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_tA36DMxmDew/SQ2t4oujjjI/AAAAAAAAAVg/eopYijMF_tU/s400-R/code.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_tA36DMxmDew/SQ2u5LXkG7I/AAAAAAAAAVo/VXET4DD2tVY/s1600-h/code2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_tA36DMxmDew/SQ2u5LXkG7I/AAAAAAAAAVo/Ugfl4j7QHCQ/s400-R/code2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Back to XPO&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
So, most of the above has been about PostSharp.&amp;nbsp; Specific to XPO, the custom attribute I have added is the AssociationAttribute required by XPO to link the two sides of the association.&amp;nbsp; So, I started with a one-way association and have used PostSharp to magically turn that into a two-way one-many association.&lt;br /&gt;
&lt;br /&gt;
If you want the code, you can get it from &lt;a href="http://www.codeplex.com/xpooneway"&gt;here&lt;/a&gt;.&amp;nbsp; Note that I've put up the XPO version and a version that doesn't require XPO.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Update: I've edited this to show that the XPCollection were the generic XPCollection&lt;t&gt; 12-Nov-2008. &lt;/t&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-1365474236444176473?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/pEy6e8_5m68/using-postsharp-to-allow-one-way.html</link><author>noreply@blogger.com (Sean Kearon)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_tA36DMxmDew/SQ2nDqb7hzI/AAAAAAAAAVY/iWOJNoTI98c/s72-Rc/Untitled.png" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/10/using-postsharp-to-allow-one-way.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-1846750675498374595</guid><pubDate>Mon, 27 Oct 2008 20:22:00 +0000</pubDate><atom:updated>2008-10-31T00:06:39.256Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">xpo</category><category domain="http://www.blogger.com/atom/ns#">devexpress</category><category domain="http://www.blogger.com/atom/ns#">postsharp</category><title>Using C# Automatic Properties with XPO Objects - Part 2</title><description>In &lt;a href="http://kearon.blogspot.com/2008/10/using-c-automatic-properties-with-xpo.html"&gt;part 1&lt;/a&gt; we looked at how XPO implements change tracking by utilising some magic from the base &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;XPObject &lt;/span&gt;class.&amp;nbsp; An XPO object looked something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class Customer&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;: XPObject&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; private DateTime date;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public DateTime Date&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; get { return date; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { SetPropertyValue("Date", ref date, value); }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; [Association("CustomerOrders", typeof(&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Order&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;))]&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public XPCollection&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Order&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Order&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return GetCollection&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Order&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;gt;("&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Order&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s"); }&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Wanting to cut down on the syntatic noise, I'd like to be able to use &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/03/08/new-c-orcas-language-features-automatic-properties-object-initializers-and-collection-initializers.aspx"&gt;C# automatic properties&lt;/a&gt; to make my classes to look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[XpoAutomaticProperties]&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class Customer&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;: XPObject&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; &lt;/span&gt; &lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public DateTime Date { get; set; }&lt;/div&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; [Association("CustomerOrders", typeof(&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Order&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;))]&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public XPCollection&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Order&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Order&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get; private set;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The secret here is the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;XpoAutomaticProperties&lt;/span&gt; attribute and the work that this does.&amp;nbsp; Applying this attribute to the class makes two things happen:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Changing a property value will raise the changed notification events.&lt;/li&gt;
&lt;li&gt;Accessing a collection will instantiate and set up the collection.&lt;/li&gt;
&lt;/ul&gt;XPO objects notify observers of changesto values using a &lt;a href="http://www.devexpress.com/Help/?document=xpo/devexpressxpoxpobject_fieldstopic0.htm"&gt;changed event&lt;/a&gt;.&amp;nbsp; Collections have similar events events are fired when the &lt;a href="http://www.devexpress.com/Help/?document=xpo/devexpressxpoxpobject_fieldstopic0.htm"&gt;collection changes&lt;/a&gt; or when an item in the &lt;a href="http://www.devexpress.com/Help/?document=xpo/devexpressxpoxpobject_fieldstopic0.htm"&gt;collection changes&lt;/a&gt;.&amp;nbsp; Note also that the GetCollection&lt;t&gt; method above sets up the collection so that it is aware of being a property of a containing object.&amp;nbsp; This will also be handled by the attribute.&lt;/t&gt;&lt;br /&gt;
&lt;br /&gt;
Along with the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;XpoAutomaticProperties&lt;/span&gt; attribute, there is one other thing that is introduced.&amp;nbsp; The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SetPropertyValue&lt;/span&gt; call is responsible for firing the changed event.&amp;nbsp; I will introduce to allow me to call back to an object to instruct it to notify observers of changes (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;XPObject&lt;/span&gt; has exactly such a method).&amp;nbsp; The interface looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public interface IPropertyChangedNotifier&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; void OnChanged(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string propertyName,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; object oldValue,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; object newValue);&lt;br /&gt;
}&lt;/div&gt;&lt;br /&gt;
Okay, if you've got this far, you must be wondering how do we actually do this?&amp;nbsp; The answer is that we use the incredible &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt; to help us add the required code we need into our objects.&amp;nbsp; PostSharp is an &lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming"&gt;aspect oriented programming&lt;/a&gt; (AOP) library and toolset that makes it easy to add code into your objects during compilation.&amp;nbsp; As the changes occur at compile time, you avoid the runtime performance hits that would come from using reflection.&lt;br /&gt;
&lt;br /&gt;
PostSharp makes the process of generating and adding IL code to your assemblies at compile time ridiculously easy to acheive for such a complex task.&amp;nbsp; Although PostSharp allows you to drop down and weave any IL code you like into your assemblies, there is a&amp;nbsp; The &lt;a href="http://www.postsharp.org/"&gt;PostSharp website&lt;/a&gt; has a number of excellent examples of how to work with PostSharp, which are extremely impressive and worth checking out.&amp;nbsp; It is also very &lt;a href="http://www.postsharp.org/about/documentation/"&gt;well&lt;/a&gt; &lt;a href="http://doc.postsharp.org/1.0/"&gt;documented&lt;/a&gt;.&amp;nbsp; PostSharp is an open source library that is free even for commercial use and, incredibly, is the work of one man: &lt;a href="http://gael.fraiteur.net/"&gt;Gael Fraiteur&lt;/a&gt;.&amp;nbsp; Everything that we do here is based on the excellent examples that Gael provides with PostSharp, so check those out when you can.&lt;br /&gt;
&lt;br /&gt;
From this point on, I am going to assume that you have some knowledge of AOP and PostSharp.&amp;nbsp; So, back to the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;XpoAutomaticProperties&lt;/span&gt; attribute and how this works.&amp;nbsp; The attribute is a PostSharp attribute in which you override a base method to do the work.&amp;nbsp; The method looks like:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public override void ProvideAspects(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; object targetElement,&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; LaosReflectionAspectCollection collection)&lt;/div&gt;&lt;br /&gt;
Inside this method you use reflection to interrogate the properties of the type and then add some code to that property like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;1 if (property.CanWrite &amp;amp;&amp;amp; property.CanRead &amp;amp;&amp;amp; !property.IsCollection())&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;2 {&lt;br /&gt;
3 &amp;nbsp; var setMethod = property.GetSetMethod(true);&lt;br /&gt;
4 &amp;nbsp; if (!setMethod.IsStatic)&lt;br /&gt;
5 &amp;nbsp; {&lt;br /&gt;
6&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; var aspect = new PropertyChangedNotifierSubAspect(&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this, property.Name);&lt;br /&gt;
7&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; collection.AddAspect(setMethod, aspect);&lt;br /&gt;
8 &amp;nbsp; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;9 }&lt;/div&gt;&lt;br /&gt;
Remember that all this code is firing at &lt;i&gt;compile time&lt;/i&gt; so the reflection will not affect your runtime performance!&amp;nbsp; So, in line 1 we check that the property (a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PropertyInfo&lt;/span&gt;) is read-write and is not a collection.&amp;nbsp; We then use reflection to access the property's setter in line 3 and check that we are not looking at a static property in line 4.&amp;nbsp; In line 6 we create a new PostSharp &lt;a href="http://doc.postsharp.org/1.0/"&gt;aspect&lt;/a&gt; - the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PropertyChangedNotifierSubAspect&lt;/span&gt; - and add it to the collection that PostSharp supplies.&amp;nbsp; Note that the name of the property is passed in to the aspect's constructor - this is how we avoid the use of string literals for property names.&amp;nbsp; After this, PostSharp does all the work for you.&amp;nbsp; Well, PostSharp does the IL weaving for you, there's still a little more for us to do.&lt;br /&gt;
&lt;br /&gt;
The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PropertyChangedNotifierSubAspect&lt;/span&gt; decends from the built in PostSharp type &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;OnMethodBoundaryAspect&lt;/span&gt;. This allows you to easily acheive a &lt;a href="http://doc.postsharp.org/1.0/"&gt;number of things&lt;/a&gt; when a method is called in your code. We use two of these to change the property's setter: first we store the old value when the setter is entered, then when the setter method completes we determine if the value has changed and fire the changed event accordingly.&amp;nbsp; PostSharp elegantly provides us methods that we can override to achieve all this - we never even have to leave C# or think about IL.&amp;nbsp; This is how we store the existing value when we enter the property's setter:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;1 public override void OnEntry(MethodExecutionEventArgs eventArgs)&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;2 {&lt;br /&gt;
3 &amp;nbsp; base.OnEntry(eventArgs);&lt;br /&gt;
4 &amp;nbsp; var instance = (XPBaseObject) eventArgs.Instance;&lt;br /&gt;
5 &amp;nbsp; oldValue = instance.GetMemberValue(propertyName);&lt;br /&gt;
6 } &lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We simply override the base class method and use the data supplied argument's to access the object whose property has changed.&amp;nbsp; We cast it to be an &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;XPBaseObject&lt;/span&gt; and use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GetMemberValue&lt;/span&gt; to access and store the value of the property on entry.&amp;nbsp; Note here that the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GetMemberValue&lt;/span&gt; is supplied by Developer Express and is performance efficient (itself using generated IL to access the property value).&amp;nbsp; If you are using XPO with your own objects that do not subclass the built in XPO types then you will have to use reflection or some other means to access the entry value.&amp;nbsp; Note also that this code is executes at runtime.&lt;br /&gt;
&lt;br /&gt;
In a similar manner, we then override the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;OnSuccess&lt;/span&gt; method to execute code when the method successfully completes (i.e. exiting with no unhandled exceptions).&amp;nbsp; At this stage, we compare the current value with the existing and fire the changed event if needed.&amp;nbsp; The code looks like:&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;1 public override void OnSuccess(MethodExecutionEventArgs eventArgs)&lt;br /&gt;
2 {&lt;br /&gt;
3&amp;nbsp; &amp;nbsp; if (!(eventArgs.Instance is IPropertyChangedNotifier)) return;&lt;br /&gt;
4&amp;nbsp; &amp;nbsp; var newValue = eventArgs.GetReadOnlyArgumentArray()[0];&lt;br /&gt;
5&amp;nbsp; &amp;nbsp; if (ValuesEqual(oldValue, newValue)) return;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &lt;br /&gt;
6&amp;nbsp; &amp;nbsp; var instance = (IPropertyChangedNotifier) eventArgs.Instance;&lt;br /&gt;
7&amp;nbsp; &amp;nbsp; instance.OnChanged(propertyName, oldValue, newValue);&lt;br /&gt;
8 } &lt;/div&gt;&lt;br /&gt;
&amp;nbsp;Again, PostSharp supplies us with event args that allow easy access to values.&amp;nbsp; We also use our &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;IPropertyChangedNotifier&lt;/span&gt; interface to do the notification.&amp;nbsp; In line 4 we access the new property value from the event arguments supplied by PostSharp (again, no reflection needed!) then call a method to check for changes in line 5.&amp;nbsp; If we have a change to the property, we instruct the object to notify the world of the change in lines 6 and 7.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Okay, so where are we now?&amp;nbsp; We've used PostSharp to create a special attribute.&amp;nbsp; We've applied the attribute to the classes in which we want to use automatic properties.&amp;nbsp; PostSharp recognises our attribute and injects code into our assemblies at &lt;i&gt;compile time&lt;/i&gt;.&amp;nbsp; The code that is injected is defined by us in classes that we create from buit in PostSharp types.&amp;nbsp; These types are called aspects and we used the one that allows us to modify a method - specifically, the property's setter method.&amp;nbsp; To modify the method was pretty easy - we just override a couple of methods and use the information that PostSharp passes back to us to do what we want.&lt;br /&gt;
&lt;br /&gt;
PostShapr also allows you to work with fields and add code to when the fields are accessed.&amp;nbsp; The way I initialise collections use this feature of PostSharp, but I'd suggest you head for the &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt; site to learn more of what you can do with PostSharp.&lt;br /&gt;
&lt;br /&gt;
Before we leave this, there's one gotcha to be aware of: the release version of PostSharp, 1.0, does not play well in partial trust scenarios.&amp;nbsp; If this is important to you then you'll be pleased to know that the next release 1.5 addresses this and version 1.5 is in &lt;a href="http://www.postsharp.org/blog/2008/10/announcing-postsharp-15-ctp-2/"&gt;CTP2&lt;/a&gt; stage at time of writing.&lt;br /&gt;
&lt;br /&gt;
If you want more, then you can get the code from &lt;a href="http://www.codeplex.com/xpoautoproperties"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-1846750675498374595?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/k16baA-zBFc/using-c-automatic-properties-with-xpo_27.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>2</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/10/using-c-automatic-properties-with-xpo_27.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-8420619752943107815</guid><pubDate>Sun, 26 Oct 2008 11:50:00 +0000</pubDate><atom:updated>2008-10-31T00:07:02.047Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">xpo</category><category domain="http://www.blogger.com/atom/ns#">devexpress</category><title>Using C# Automatic Properties with XPO Objects - Part 1</title><description>In my &lt;a href="http://kearon.blogspot.com/2008/10/orm-with-developer-express-persistent.html"&gt;previous post&lt;/a&gt; I touched on the fact that objects in Express Persistent Objects (&lt;a href="http://www.devexpress.com/Products/NET/ORM/"&gt;XPO&lt;/a&gt;) support change tracking.  One area that this is used by their &lt;a href="http://martinfowler.com/eaaCatalog/unitOfWork.html"&gt;Unit of Work&lt;/a&gt; to track the changes made to objects.  Another use is when data binding objects to a UI.  So, how do you enable change tracking in your object model using XPO?&lt;br /&gt;
&lt;br /&gt;
XPO supports a variety of methods for &lt;a href="http://www.devexpress.com/Help/?document=XPO/CustomDocument2108.htm&amp;amp;levelup=true"&gt;achieving this&lt;/a&gt;, but the easiest is to inherit your domain objects from &lt;span style="font-family: &amp;quot;&amp;quot;;"&gt;XPObject&lt;/span&gt;.  When you do this change tracking is enabled by calling a magic setter method in your property setters and using their built-in collection type for association properties:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class Customer: XPObject &lt;/div&gt;&lt;div face="&amp;quot;" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div face="&amp;quot;" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; private DateTime date;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public DateTime Date&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return date; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetPropertyValue("Date", ref date, value);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; [Association("CustomerOrders", typeof(Order))]  &lt;br /&gt;
&amp;nbsp; public XPCollection&amp;lt;Order&amp;gt; Orders &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; { &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return GetCollection&amp;lt;Order&amp;gt;("Orders"); } &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;br /&gt;
}&lt;/div&gt;&lt;br /&gt;
Note that &lt;span style="font-family: &amp;quot;&amp;quot;;"&gt;Association&lt;/span&gt; attribute on the collection property is required by XPO and indicates that the property is one end of a two-way association - either one-many or many-many.  Associations are always two-way, except one-one associations which are &lt;a href="http://www.devexpress.com/Help/?document=Xpo/CustomDocument2046.htm"&gt;handled differently&lt;/a&gt;.  So, for completeness, with the example above being a one-many relationship, you will need the following to express the other end:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class Order: XPObject &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; private Customer customer;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; [Association("CustomerOrders")]&lt;br /&gt;
&amp;nbsp; public Customer Customer&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; { &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return customer; } &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetPropertyValue("Customer", ref customer, value);&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; } &amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;br /&gt;
It makes sense to use a collection type that supports change notification and the calls to &lt;span style="font-family: &amp;quot;&amp;quot;;"&gt;SetPropertyValue&lt;/span&gt; are a fairly elegant way to notify change.  Okay, this is all good, but I like to cut down the syntactic noise as far as possible.  This basically means that I want to to use &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/03/08/new-c-orcas-language-features-automatic-properties-object-initializers-and-collection-initializers.aspx"&gt;C# automatic properties (&lt;/a&gt;and I also don't want get into using &lt;a href="http://draft.blogger.com/goog_1225095348515"&gt;&lt;span style="font-family: &amp;quot;&amp;quot;;"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.devexpress.com/Help/?document=xpo/devexpressxpoxpobject_fieldstopic0.htm"&gt;design time code generation techniques&lt;/a&gt; to help me out).  So, where do we go from here?  We go to this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[XpoAutomaticProperties]&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class Customer: XPObject &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public DateTime Date { get; set; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;  [Association("CustomerOrders", typeof(Order))]&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public XPCollection&amp;lt;Order&amp;gt; Orders&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get; private set;&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[XpoAutomaticProperties]&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;public class Order: XPObject &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; [Association("CustomerOrders")]&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; public Customer Customer&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get; private set;&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;br /&gt;
The classes above will give the same functionality - change tracking and collection creation - as the previous examples.  Except, there is much less code to read, just automatic properties and an extra attribute on the class declaration.  Take a look at &lt;a href="http://kearon.blogspot.com/2008/10/using-c-automatic-properties-with-xpo_27.html"&gt;part 2&lt;/a&gt; to see how this can be done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-8420619752943107815?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/-91a5pnFTKc/using-c-automatic-properties-with-xpo.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>2</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/10/using-c-automatic-properties-with-xpo.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-4201033444121680120</guid><pubDate>Fri, 24 Oct 2008 10:33:00 +0000</pubDate><atom:updated>2008-10-31T00:07:19.707Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">xpo</category><category domain="http://www.blogger.com/atom/ns#">devexpress</category><title>ORM with Developer Express Persistent Objects (XPO)</title><description>I've been using &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping"&gt;ORM&lt;/a&gt;s for a long while now and love the speed and flexibility they can bring to the development process. For projects in&amp;nbsp; work we use an ORM that we wrote ourselves.&amp;nbsp; As I'm now doing some projects outside of my day job, I have been looking around at the available ORM offerings for a few months now.&amp;nbsp; I'm now pretty likely to be using &lt;a href="http://www.devexpress.com/Products/NET/ORM/"&gt;Express Persistent Objects&lt;/a&gt; (XPO) from &lt;a href="http://www.devexpress.com/"&gt;Developer Express&lt;/a&gt; -  a developer tool vendor with an excellent reputation and strong background.&lt;br /&gt;
&lt;br /&gt;
I've been evaluating their UI controls for a while now and I have been generally very impressed with both their products and their excellent support.&amp;nbsp; XPO comes from this background and has the main features that I want: &lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Support for the Compact Framework.&lt;/li&gt;
&lt;li&gt;A LINQ provider.&lt;/li&gt;
&lt;li&gt;Generation of schema from object definitions (you can also generate objects from an existing schema).&lt;/li&gt;
&lt;li&gt;Wide support for a &lt;a href="http://www.devexpress.com/Help/?document=XPO"&gt;variety of databases&lt;/a&gt; (including my target database, &lt;a href="http://www.vistadb.net/"&gt;VistaDB&lt;/a&gt;).&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Easy data binding of objects to controls (as you'd expect from DevExpress!).&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
It does have a few quirks that I'm a little unsure about at the moment.&amp;nbsp; The main ones for me now are:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;All associations with multiplicity greater than one have to be two-way.&lt;/li&gt;
&lt;li&gt;The automatic schema generation mechanism will not widen string fields in existing schemas.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;I also get the feeling from reading their forums that XPO gets a "little less love" than some of their other products.&amp;nbsp; I think that it may be seen as either largely functionally complete, or that it now plays a supporting role to their application framework, &lt;a href="http://www.devexpress.com/Products/NET/Application_Framework/"&gt;XAF&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
However, these are only small niggles and the product is seems to be well constructed, uses best practices, has good support from a much respected tool vendor and is realistically priced.&amp;nbsp; If you are coming to ORM from a data-driven background, then you will probably even be comfortable with having to always having to have have two sides to an association!&amp;nbsp; It is worth noting that XPO takes care of the other end of the relationship for you - if I add an order to a customer, then the order's customer is automatically set...neat and sweet!&lt;br /&gt;
&lt;br /&gt;
If you are looking for an easy to use commercial ORM that is reasonably priced, then I would recommend you take a look.&amp;nbsp;&amp;nbsp; If you are not looking for a non-commercial ORM, or want to learn about the world of object-relational mapping, then head off to &lt;a href="http://blogs.hibernatingrhinos.com/nhibernate/Default.aspx"&gt;NHibernate&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Edit: Just thought it worth noting that the "small niggles" about XPO are in the context of my current project, which has a relatively simple object model - one for which I would happily manually write the data access code.&amp;nbsp; I would not be comfortable recommending XPO for complex object models at this stage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-4201033444121680120?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/IP7vyIfmD94/orm-with-developer-express-persistent.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>2</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/10/orm-with-developer-express-persistent.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-578838426113782549</guid><pubDate>Thu, 26 Jun 2008 19:51:00 +0000</pubDate><atom:updated>2009-04-18T09:16:23.499+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">production</category><title>Praise: Subversion Hosting at Wush.net</title><description>I've recently signed up for &lt;a href="http://subversion.tigris.org/"&gt;Subversion &lt;/a&gt;hosting with &lt;a href="http://wush.net/subversion.ph"&gt;Wush&lt;/a&gt;.  I spent a long time looking at various online providers before deciding on Wush.  I am more than happy with my choice!&lt;br /&gt;&lt;br /&gt;I currently have a no-frills service with a gigabyte of space with unlimited users across a single Subversion repository for $20USD per &lt;span style="font-style: italic;"&gt;quarter&lt;/span&gt; at time of writing.  (You can add extra Subversion repositories for $5USD.) &lt;br /&gt;&lt;br /&gt;Hey, I don't want frills, I want service and Wush have given me absolutely top class service!  Their service started when I was asking initial questions and has continued through my teething problems (like not remembering how to set up other users; how to integrate with FogBugz, etc.).&lt;br /&gt;&lt;br /&gt;There are a lot of good looking offerings out there with some very slick interfaces.  However, these often took, literally, days to respond to my support requests.  Sorry - not good enough!! &lt;br /&gt;&lt;br /&gt;Wush does not have a slick interface but has a strong, consistent and solid level of support from the start. &lt;br /&gt;&lt;br /&gt;When a job's done right, you have to say so: Wush have to be one of the best out there and I wholeheartedly recommend them!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-578838426113782549?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/OD7fSHMsnvQ/praise-subversion-hosting-at-wushnet.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/06/praise-subversion-hosting-at-wushnet.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-4307989067101460572</guid><pubDate>Mon, 23 Jun 2008 23:30:00 +0000</pubDate><atom:updated>2009-04-18T09:20:33.799+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">eco</category><title>ECO VistaDB Provider on CodePlex</title><description>I've put the code for the ECO VistaDB Provider up on CodePlex.  Get if from:&lt;br /&gt;
&lt;blockquote&gt;&lt;a href="http://www.codeplex.com/ecovistadbprovider"&gt;http://www.codeplex.com/ecovistadbprovider&lt;/a&gt;&lt;/blockquote&gt;I'd be very interested to hear of any experiences if you use it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-4307989067101460572?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/YRbl343VvL4/eco-vistadb-provider-on-codeplex.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/06/eco-vistadb-provider-on-codeplex.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-5452503643568523688</guid><pubDate>Sun, 22 Jun 2008 09:37:00 +0000</pubDate><atom:updated>2008-08-14T18:08:12.753+01:00</atom:updated><title>Flintstone Machine: Enterprise Integration Pattern</title><description>In the &lt;a href="http://en.wikipedia.org/wiki/The_Flintstones"&gt;&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/The_Flintstones"&gt;Flintstones&lt;/a&gt; cartoon, the "modern stone age" families used used machines that were functionally equivalent to the contemporary household utility appliances, but were powered by animals inside.  For example, in the recent film, their garbage collector chute leads to a pig in the cupboard that eats all the waste food.&lt;br /&gt;&lt;br /&gt;In enterprise IT systems we find similar things: systems that hand off work to a human worker when that work could be accomplished by the system or passed to another system.  The worker becomes the equivalent of the animals inside the Flintstones' machines.&lt;br /&gt;&lt;br /&gt;The key feature is that the task the worker performs could be done, in whole or in part by software; indicating areas where greater operational efficiencies &lt;span style="font-style: italic;"&gt;may &lt;/span&gt;be achieved.  Of course, it does not indicate that there is a cost benefit to making the change!&lt;br /&gt;&lt;br /&gt;This can make sense as a temporary step on the journey toward greater integration.  To keep your promises, you might roll out your online ordering system to the world and start taking orders today, before you can bring the warehousing system to the party.  You have a team of people working like hell to take the orders to the warehouse and update the stock levels.  The warehousing integration rolls out later.&lt;br /&gt;&lt;br /&gt;The enterprise system is like a swan, the surface is all graceful and efficient, while the legs are working like hell to move things along!&lt;br /&gt;&lt;br /&gt;Also see: &lt;a href="http://bill-poole.blogspot.com/2008/05/swivel-chair-integration-is-bad.html"&gt;Swivel Chair Integration&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-5452503643568523688?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/98NHun0S9T8/flintstone-machine-enterprise-anti.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/06/flintstone-machine-enterprise-anti.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-8359646654553156710</guid><pubDate>Thu, 19 Jun 2008 20:53:00 +0000</pubDate><atom:updated>2009-04-18T08:02:24.152+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">windowsvista</category><title>UAC: Peace at Last</title><description>&lt;blockquote style="font-style: italic;"&gt;Caveat: do not try this at home unless you understand and are willing to accept the reduced security.  Read the comments in the link below for more details.&lt;/blockquote&gt;That said, I've found some &lt;a href="http://www.howtogeek.com/howto/windows-vista/disable-user-account-controluac-for-administrators-only/"&gt;valium for the soul&lt;/a&gt;!  The howtogeek.com article shows how to automatically elevate for the admin accounts on my machine.  I've set this up and have just gone to delete some bin and obj folders as I did &lt;a href="http://kearon.blogspot.com/2008/06/uac-time-is-marked.html"&gt;last night&lt;/a&gt;.  However, tonight I feel positively warm and glowing - it simply asked me to confirm the deletion and then they disappear.&lt;br /&gt;&lt;br /&gt;Bliss!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-8359646654553156710?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/ynjkQR7lgFg/uac-peace-at-last.html</link><author>noreply@blogger.com (Sean Kearon)</author><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/06/uac-peace-at-last.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2285278671879033267.post-4468302968309132089</guid><pubDate>Wed, 18 Jun 2008 23:37:00 +0000</pubDate><atom:updated>2008-11-30T16:20:59.106Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">windowsvista</category><title>UAC: Your Time is Marked!</title><description>Before zipping the source for the last post, I went to remove the bin and obj folders.  These are located in my documents folder (under the VS2008 projects folder).  My &lt;span id="SPELLING_ERROR_0"&gt;login&lt;/span&gt; has admin rights to the machine and I'm not on any domain either - just a standalone home machine!&lt;br /&gt;
&lt;br /&gt;
Life should be sweet then?  Well, not if you're using Windows Vista with &lt;span id="SPELLING_ERROR_1"&gt;UAC&lt;/span&gt; enabled.  There are seeming endless requests for permission to continue.  It's a click multiplier...the more you want to do, the more you have to click!&lt;br /&gt;
&lt;br /&gt;
I began by thinking that it's all worth while, it's for security reasons, etc. etc.  Right now I'm at the end of my tether and am about to turn it off.&lt;br /&gt;
&lt;br /&gt;
One of my favourites is that when trying to delete the bin/obj folders, I can't!  I just get the following:&lt;span style="text-decoration: underline;"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;a href="http://bp1.blogger.com/_tA36DMxmDew/SFmcbBlya2I/AAAAAAAAAQU/fIm43hYoUy4/s1600-h/vista.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5213370031755389794" src="http://bp1.blogger.com/_tA36DMxmDew/SFmcbBlya2I/AAAAAAAAAQU/fIm43hYoUy4/s320/vista.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;I&lt;/span&gt; created these folders, inside &lt;span style="font-style: italic;"&gt;my&lt;/span&gt; user profile, on &lt;span style="font-style: italic;"&gt;my&lt;/span&gt; machine, upon which &lt;span style="font-style: italic;"&gt;I&lt;/span&gt; have full administrative rights.  There were &lt;span style="font-style: italic;"&gt;no&lt;/span&gt; &lt;a href="http://ccollomb.free.fr/unlocker/"&gt;files locked&lt;/a&gt; by other processes (&lt;span id="SPELLING_ERROR_2"&gt;merci&lt;/span&gt;, &lt;span id="SPELLING_ERROR_3"&gt;Cedrick&lt;/span&gt;!).  &lt;span style="font-style: italic;"&gt;I&lt;/span&gt; had only created the folders a few minutes previously.  Man, this is the most tedious version of Windows I have ever used.  This stuff drives me insane!&lt;br /&gt;
&lt;br /&gt;
Sometimes when I get the dialog above, if I go into the folder and delete files and &lt;span id="SPELLING_ERROR_4"&gt;subfolders&lt;/span&gt; before I delete the main folder, I get to delete the main folder after all that.  Wow, that's great, there's a workaround!  Well, no - it doesn't &lt;span style="font-style: italic;"&gt;always&lt;/span&gt; work, just sometimes!!&lt;br /&gt;
&lt;br /&gt;
Vista &lt;span id="SPELLING_ERROR_5"&gt;UAC&lt;/span&gt; - your time is marked!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2285278671879033267-4468302968309132089?l=kearon.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/AtlanticBreeze/~3/1v7UT7Z4Cd0/uac-time-is-marked.html</link><author>noreply@blogger.com (Sean Kearon)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp1.blogger.com/_tA36DMxmDew/SFmcbBlya2I/AAAAAAAAAQU/fIm43hYoUy4/s72-c/vista.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://kearon.blogspot.com/2008/06/uac-time-is-marked.html</feedburner:origLink></item></channel></rss>

