<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-7806605514179331942</atom:id><lastBuildDate>Mon, 20 Oct 2025 07:02:43 +0000</lastBuildDate><category>Best Practices</category><category>TDD</category><category>DDD</category><category>Dependency Injection</category><category>Testing</category><category>tools</category><category>alt.net</category><category>communication</category><category>NHibernate</category><category>Unit Testing</category><category>AOP</category><category>Design By Contract</category><category>Productivity</category><category>Refactoring</category><category>Database</category><category>PowerShell</category><category>SOA</category><category>Visual Studio</category><category>Wcf</category><category>asp.net</category><category>.net</category><category>Castle</category><category>Code Generation</category><category>Documentation</category><category>Encapsulation</category><category>Mac</category><category>MassTransit</category><category>ORM</category><category>Python</category><category>Sandcastle</category><category>employment</category><category>Agile</category><category>Books</category><category>BreadCrumbs</category><category>Build tools</category><category>DTO&#39;s</category><category>ESB</category><category>MSMQ</category><category>MVC</category><category>Maintenance</category><category>Microsoft</category><category>PnP</category><category>Project Management</category><category>SQL</category><category>Security</category><category>SilverLight</category><category>User Controls</category><category>Web Services</category><category>programming</category><category>AJAX</category><category>Boo</category><category>Continuous Integration</category><category>Education</category><category>IronPython</category><category>Languages</category><category>Logging</category><category>OO</category><category>Object Builder</category><category>PostSharp</category><category>QueryString</category><category>Quote</category><category>Rhino Mocks</category><category>Ruby</category><category>SiteMaps</category><category>Specification</category><category>WPF/e</category><category>events</category><category>motivation</category><category>patterns</category><category>.net 4</category><category>Amazon</category><category>BDD</category><category>Build</category><category>Code Snippets</category><category>DAO</category><category>DSL</category><category>Deployment</category><category>Document Databases</category><category>Dojo</category><category>EntLib</category><category>Google Maps</category><category>Greenfields</category><category>Holidays</category><category>ICloneable</category><category>Intellisense</category><category>Interoperability</category><category>JavaScript</category><category>MSBuild</category><category>MSTest</category><category>Mocks</category><category>NMock</category><category>Ninject</category><category>Normalisation</category><category>OSS</category><category>Oracle</category><category>PITA</category><category>Paint.Net</category><category>Parallel programming</category><category>Pex</category><category>Rancid</category><category>RavenDb</category><category>Rx</category><category>Serialization</category><category>Source Control</category><category>TFS</category><category>TeamCity</category><category>Technical Debt</category><category>UML</category><category>Unity</category><category>VMware</category><category>VS Templates</category><category>Video editing</category><category>Volta</category><category>WPF</category><category>WinForms</category><category>XML</category><category>XSD</category><category>dOOdads</category><category>event scheduling</category><category>exceptions</category><category>infragistics</category><category>jQuery</category><category>linq2sql</category><category>multi core</category><category>nunit</category><category>openspaces</category><category>recurring events</category><category>solution file</category><category>stuff</category><category>threading</category><category>vacation</category><category>vss</category><category>web presence</category><category>xbox</category><title>Ramblings from Rhys</title><description>A .Net blog with ramblings on code and other assorted things from a joe average developer.</description><link>http://rhysc.blogspot.com/</link><managingEditor>noreply@blogger.com (Anonymous)</managingEditor><generator>Blogger</generator><openSearch:totalResults>253</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-8111903079882376136</guid><pubDate>Sun, 08 Jul 2012 23:06:00 +0000</pubDate><atom:updated>2012-07-08T16:06:51.286-07:00</atom:updated><title>Lessons Learnt - Building an SDP</title><description>I was recently asked what lessons had I learnt in regards to building an SDP and I thought it was an interesting question in many aspects and a question I would attempt explore in the form of a post on this blog.&lt;br /&gt;
Now to prefix this post I am obviously only a cog in the many wheels it takes to build a product like a &lt;a href=&quot;http://en.wikipedia.org/wiki/Single-dealer_platform&quot;&gt;Single Dealer Platform&lt;/a&gt;&amp;nbsp;and these opinions are&amp;nbsp;solely&amp;nbsp;mine and many members of the team, past and present, will obviously ave differing opinions. The &lt;a href=&quot;http://alphainfo.socgen.com/&quot;&gt;Alpha&lt;/a&gt; platform has had its ups and downs, as had the whole market, however I am pleased to say it is a successful and profitable multi asset platform and I am proud to have played a part in its success. That being said there are things that could have smoothed the sometime bumpy ride. However I dont feel it is fair to throw stones as many of these&amp;nbsp;problems&amp;nbsp;are industry wide and we have interesting issue of having two&amp;nbsp;industries&amp;nbsp;to deal with, finance and technology and to ease the thought process in this post I&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp;will take the question and rephrase to if you had to build an SDP what would focus on?&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;Form Key Relationships&lt;/span&gt;&lt;/h2&gt;
&lt;h3&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;Business Buy-In&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;The platform should be supporting the business and not conflicting with exiting goals and other teams strategies. If you have sales teams or team members that feel the product is competition you need to get them on board or you risk having to work&amp;nbsp;against&amp;nbsp;their&amp;nbsp;negative&amp;nbsp;energy. Sales and traders can have significant sway in the bank so obviously having them as allies make for a much smoother project. The opposition to new&amp;nbsp;products&amp;nbsp;is not isolated to these profiles. Anyone who has developed software internal in a corporation will have come up against this, so it is a common problem we must over come. &amp;nbsp;Given the platform should enhance their daily dealings by being able to provide up and cross selling facilities as well as a portal-like&amp;nbsp;experience&amp;nbsp;into&amp;nbsp;research&amp;nbsp;and post trade facilities, the product should actually be a good thing for the sales desks. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h3&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;Backend Systems&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;Be prepared &amp;nbsp;- Front end systems like SDPs do not work without good service &amp;nbsp;from the various providers required to price and book trades. There is more to an SDP than this, however these systems are key. Work closely with these teams - the are your life blood. When delivery times are tight you may have to call in favours from these teams. At a business level these teams goals must have some alignment with that of the SDP or their work slate will continually be serving other priorities. To have a beautiful fornt end that is not integrated is an effort in futility and will quickly&amp;nbsp;raise&amp;nbsp;concerns from the bill payers.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h2&gt;
Clear Vision&lt;/h2&gt;
Firstly know your strengths and play to them. Every bank cant not be the best in FX. Although most SDPs will have a strong FX and Fixed income feature set, trying to have the best prices and lowest&amp;nbsp;latency&amp;nbsp;is a costly venture. If you are going to try to take on the big boys you had better have a strong financial backer. If you are not one of&amp;nbsp;those&amp;nbsp;players, acknowledge it and find where your&amp;nbsp;strengths&amp;nbsp;are and use them. A strong product owner will be key here. His role will be to clearly understand the direction of the bank and to know what will drive the platform. He should have a clear understanding of our income sources and our user base. Defining core users is also key here. This will provide direction in the type of platform we will technically deliver : Desktop, RIA, Web, mobile or a combination should be a business&amp;nbsp;decision&amp;nbsp;based on the users of the platform, not based on the latest technical craze? Lastly we must have clear success criteria for each deliverable and the platform as a whole. When this is clear the team can easily all move in the same direction.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Deliver the Goods&lt;/h2&gt;
In my&amp;nbsp;opinion: Delivery is king.&amp;nbsp;Continuous&amp;nbsp;delivery is a logical progression of a well oiled development team. To achieve continuous delivery you should address some key, common concerns early in the project. Authentication and&amp;nbsp;authorisation,&amp;nbsp;handling of entitlements, security concerns, auditing, logging and other such cross cutting concerns are all usually defined by the bank at a department or group level. IMO these should be addressed in the first iteration while other team&amp;nbsp;members&amp;nbsp;could possibly be working on PoCs realting to&amp;nbsp;functional&amp;nbsp;deliverables. This is also a good time to investigate some standard&amp;nbsp;deployment&amp;nbsp;concerns such as the handling of independent and&amp;nbsp;aggregated&amp;nbsp;modules, dependency management, versioning, forward and backward&amp;nbsp;compatible&amp;nbsp;migrations. From a higher level architectural stance the team will also need to define how they could deal with future&amp;nbsp;scalability,&amp;nbsp;reliability&amp;nbsp;and regional requirements. Do we have the infrastructure to provide five 9s to a global audience with latency under 10ms? If not now is a good time to let the business know so they can lead the charge on making the&amp;nbsp;necessary&amp;nbsp;changes if required or so they can have their expectations realigned appropriately. The reason I prefer to address this early is&amp;nbsp;because&amp;nbsp;the cost is so much higher when done later in the project and delivery becomes an expectation and a core team value. It also raises the notion of non functional cost to the business; fives 9&#39;s up time is not free, nor are follow the sun deployments, the sooner the business are aware of this the better for everyone.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Justify your Costs&lt;/h2&gt;
By understanding what brings value to the business we can more appropriately prioritise our work. One major issue that I have&amp;nbsp;encountered&amp;nbsp;on many projects is the confusion of the&amp;nbsp;prioritisation&amp;nbsp;of features that generating income versus those that prevent losses or reduce the cost of doing business. Both are of value.&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;Features that I can see SDPs typically spending too much on are technical &quot;play things&quot; (new frameworks etc), performance and low value &quot;nice to haves&quot;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;. A good Product owner that has a good relation with his technical leads and architects should be able to address these issues easily.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Typical neglected features are&amp;nbsp;resiliency, monitoring&amp;nbsp;and work related to minimising&amp;nbsp;maintenance cost. No one wants to pay for any of these but we often dont&amp;nbsp;realise&amp;nbsp;we want the consequence of&amp;nbsp;&lt;i&gt;not&lt;/i&gt;&amp;nbsp;having them even less. The unfortunate thing is we often discover this far too late. IMO the key ways of reducing&amp;nbsp;maintenance&amp;nbsp;cost is clean well tested code (ie&amp;nbsp;employing&amp;nbsp;BDD and TDD).&lt;br /&gt;
Another key issue in resource allocation. It is easy to think due to the large mount of money involved in building these platforms that a large number of people should be involved. For any one who has read &lt;a href=&quot;http://www.amazon.com/The-Mythical-Man-Month-Engineering-Anniversary/dp/0201835959&quot;&gt;Fred Brooks&#39; Mythical Man-Month&lt;/a&gt;&amp;nbsp;or has managed very large software teams will know that the communication overhead of throwing more resources at the problem will most likely only&amp;nbsp;exacerbate&amp;nbsp;the problem. In&amp;nbsp;addition&amp;nbsp;to this hiring the wrong resources can also be catastrophic. Because of this I prefer, like many agile teams, to have small self&amp;nbsp;managing teams comprised of exceptional people that are completely&amp;nbsp;accountable for the delivery of their feature. The cost IMO of having&amp;nbsp;unaccountable&amp;nbsp;people or inappropriately skilled people on the delivery team is often just too high.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
Summary&lt;/h4&gt;
The person that originally asked the question would possibly be&amp;nbsp;surprised&amp;nbsp;that my answer&amp;nbsp;wasn&#39;t more technical as I think he wanted to hear&amp;nbsp;&quot;Use product X&quot;. I believe the tools used should ideally be representative of the way the team works and the product that needs to be delivered. &amp;nbsp;Now this is not&amp;nbsp;always&amp;nbsp;feasible as there will be&amp;nbsp;company&amp;nbsp;wide mandates in place,&amp;nbsp;however&amp;nbsp;how that team works within those confines can often be quite impressive.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;Like any project I believe a team led well, with a common clear direction and with members&amp;nbsp;&lt;/span&gt;driven to deliver success will find a way.&lt;br /&gt;
&lt;br /&gt;
A couple of books to me really resonate in this area, the Brooks classic as mentioned earlier and&amp;nbsp;surprisingly&amp;nbsp;to some &lt;a href=&quot;http://theartofscalability.com/&quot;&gt;The Art of S&lt;span style=&quot;background-color: white;&quot;&gt;calability&lt;/span&gt;&lt;/a&gt;. I originally bought this while working on the streaming price distribution components for Alpha but to be honest go more benefit in the non&amp;nbsp;technical&amp;nbsp;sections. The authors strongly believe a scalable system comes for a well oiled team that allows for scaling. If you are looking at starting a large scale system like an SDP would&amp;nbsp;recommend&amp;nbsp;this book for more than just the excellent&amp;nbsp;technical&amp;nbsp;read it is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;</description><link>http://rhysc.blogspot.com/2012/07/lessons-learnt-building-sdp.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-6742889512390208668</guid><pubDate>Sun, 08 Jul 2012 20:31:00 +0000</pubDate><atom:updated>2012-07-08T13:31:40.332-07:00</atom:updated><title>Back to the code</title><description>The last couple of years have been a&amp;nbsp;whirlwind&amp;nbsp;and in my time running a relatively large part of a&amp;nbsp;relatively&amp;nbsp;large project I was often unable to spend time keeping up to date in any technology other than that at hand at the present time. &amp;nbsp;I have finally been able to put my head up for some air so to speak and get my head back in the tech&amp;nbsp;world&amp;nbsp;that I feel I have turned my back on in the last 18 months. I may post more about this soon however for now it is updates on stuff I have been playing with lately.&lt;br /&gt;
&lt;br /&gt;
Im quite keen to dive back into JavaScript, which&amp;nbsp;would&amp;nbsp;have sounded&amp;nbsp;weird&amp;nbsp;to me 10 years ago as it was a&amp;nbsp;language that at the time I thought was just a hack fest. Having grown up somewhat and having more&amp;nbsp;experience&amp;nbsp;with the language it is obvious that it deserves a bit more respect than that. With HTML 5 and Windows 8 fully harnessing javascript and the acknowledgement of &lt;a href=&quot;http://nodejs.org/&quot;&gt;node.js&lt;/a&gt; as a&amp;nbsp;legitimate&amp;nbsp;backend technology, JavaScript is here to stay. As I started diving back into the JS world I&amp;nbsp;realised&amp;nbsp;that my knowledge of JS fundamentals was woefully lacking.&lt;br /&gt;
&lt;br /&gt;
My first step back into the JS journey is getting my head around what JS actually is (vs what I thought it was). Being a prototype based language and not a class based language, it offers different ways of solving similar solutions to languages I&#39;m more used to. This does not mean you cant use conventional OO based techniques, we know you can, but it means you may have to rethink how you could best solve those problems. Most of the change comes into the definition of the&amp;nbsp;objects, not so much the use of them... well... kinda. For more good reading on JS for people with OO background have a look into this nice &lt;a href=&quot;http://brianodell.net/?page_id=516&quot;&gt;blog series&lt;/a&gt; on the topic.&lt;br /&gt;
&lt;br /&gt;
One of the major steps forward in JS, as the language has not really changed, are the new APIs&amp;nbsp;available. &amp;nbsp;I have the fortune of having some friends that are in web based start ups that I can tap into as a source of up-to-date trends and whats hot in the &quot;valley&quot;. A few of those things that I have picked up lately are &lt;a href=&quot;http://documentcloud.github.com/underscore/&quot;&gt;UnderScore.js&lt;/a&gt;, &lt;a href=&quot;http://documentcloud.github.com/backbone/&quot;&gt;Backbone.js&lt;/a&gt; and in the testing realm &lt;a href=&quot;http://pivotal.github.com/jasmine/&quot;&gt;Jasmine&lt;/a&gt; and &lt;a href=&quot;http://sinonjs.org/&quot;&gt;Sinon&lt;/a&gt; for isolation/mocking.&lt;br /&gt;
&lt;br /&gt;
UnderScore is a handy utility library that provides a bunch of assistance functions especially&amp;nbsp;helpfully,&amp;nbsp;amongst&amp;nbsp;other things,&amp;nbsp;in the handling of collections. As it is a utility library its super helpful and at 1000 lines in a single file, if you really want to know how it all works, you are only an hour or two away from figuring it all out. I would certainly read through the website as it quickly and succinctly&amp;nbsp;describes all its functions. Being a .Net fan-boi, &lt;a href=&quot;http://en.wikipedia.org/wiki/Language_Integrated_Query&quot;&gt;Linq&lt;/a&gt; is dear to my heart, so I was please to see that method chaining was supported albeit not as cleanly as something like &lt;a href=&quot;http://linqjs.codeplex.com/&quot;&gt;linq.js&lt;/a&gt;, but hey you cant have everything :).&lt;br /&gt;
&lt;br /&gt;
Backbone to me is much more interesting. I have many times bumbled my way through DOM&amp;nbsp;manipulation&amp;nbsp;handling various client side events using JS. &amp;nbsp;Backbone comes to the rescue by providing a Model-View binding approach that I am much more comfortable with (at least conceptually) and leads to clean &lt;a href=&quot;http://en.wikipedia.org/wiki/Separation_of_concerns&quot;&gt;SoC&lt;/a&gt;&amp;nbsp;and a testable model, which is all good stuff.&lt;br /&gt;
Learning the basics of Backbone is not super obvious and the docs IMO are not super helpful either (I have been spoilt lately learning rails with a tonne of good docs). Fortunately the &lt;a href=&quot;https://peepcode.com/&quot;&gt;PeepCode&lt;/a&gt; &lt;a href=&quot;https://peepcode.com/products/backbone-js&quot;&gt;series&lt;/a&gt;&amp;nbsp;has been a&amp;nbsp;fantastic&amp;nbsp;resource with 3 video tutorials and the&amp;nbsp;accompanying&amp;nbsp;source code so you can follow along. &lt;br /&gt;
&lt;br /&gt;
Now there is no point in saying Backbone is super testable without testing it and Jasmine with Sinon fit in nicely here. Jasmine and Sinon are covered in the PeepCode series and also in this nice blog &lt;a href=&quot;http://tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html&quot;&gt;series&lt;/a&gt;.&lt;br /&gt;
Backbone goes a long way in addressing my issues that I had with my previous &quot;DOM&amp;nbsp;manipulation&quot;&amp;nbsp;heavy approach, and Jasmine fits hand and hand with an improve testing approach. If you are used to BDD style frameworks like &lt;a href=&quot;http://cukes.info/&quot;&gt;Cucumber&lt;/a&gt; or &lt;a href=&quot;http://specflow.org/&quot;&gt;SpecFlow&lt;/a&gt; then Jasmine maybe for you, however if you prefer standard xUnit style testing there is always&amp;nbsp;&lt;a href=&quot;http://docs.jquery.com/QUnit&quot;&gt;QUnit&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Sinon is also a nice fit with testing as Backbone has some convention based features that allow you to hit backend servers for model updates and persistence; Sinon steps in and saves you some pretty serious pain if you were serious testing your models over the wire.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;Hopefully&lt;/span&gt;&amp;nbsp;I will give some more feedback on these various APIs and approaches as I get a bit more experience in them, however for now it is just a link fest.&amp;nbsp;&lt;span style=&quot;background-color: white;&quot;&gt;Depending on how well my ventures into Backbone go I may or may not use&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/data/gg577610#js&quot;&gt;Reactive Extensions for JS&lt;/a&gt;&lt;span style=&quot;background-color: white;&quot;&gt;. Reactive Extension (RX) is something that is pervasive on the code base I currently work on so it is an obvious choice for me to&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;experiment&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp;with. RX is a brilliant API for event based data streams and is something that I think will become common place in .Net in the very near future. For more info check out &lt;a href=&quot;http://www.introtorx.com/&quot;&gt;Intro To Rx&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
See y&#39;all soon.&lt;br /&gt;
&lt;br /&gt;
Links&lt;br /&gt;
&lt;br /&gt;
https://peepcode.com/products/backbone-js/&lt;br /&gt;
https://peepcode.com/products/full-stack-nodejs-i</description><link>http://rhysc.blogspot.com/2012/07/back-to-code.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-5388002130655538218</guid><pubDate>Mon, 22 Nov 2010 11:23:00 +0000</pubDate><atom:updated>2010-11-22T03:23:41.857-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Agile</category><category domain="http://www.blogger.com/atom/ns#">tools</category><title>Agile Tools That Just Work</title><description>Here are some nice tools that I use and generally make life easier in an agile world.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Scrumy&lt;/h3&gt;&lt;a href=&quot;http://www.scrumy.com/&quot;&gt;http://www.scrumy.com&lt;/a&gt;&lt;br /&gt;
Free kanban board for managing projects (and life).&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;WebSequenceDiagrams&lt;/h3&gt;&lt;a href=&quot;http://www.websequencediagrams.com/&quot;&gt;http://www.websequencediagrams.com/&lt;/a&gt;&lt;br /&gt;
Quick way to create sequence diagrams and the input is text meaning its easy to share with other that don&#39;t have tools like Visio or EA etc. I actually prefer this to visio and our scrum team used it a lot in our last delivery.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;SpecFlow&lt;/h3&gt;&lt;a href=&quot;http://specflow.org/&quot;&gt;http://specflow.org/&lt;/a&gt;&lt;br /&gt;
I like &lt;a href=&quot;http://fitnesse.org/&quot;&gt;Fitnesse&lt;/a&gt; but there is too much friction (not a lot, but enough) in terms of the development cycle (e.g. its odd source control management). SpecFlow is close enough to cucumber for me (in the .Net world) and does not rely on Ruby to be installed. Ruby installs on windows are still a complete PITA as far as I&#39;m concerned and I&#39;ll generally do anything to avoid it. SpecFlow also runs with your existing (x/n/mb)unit testing tool of choice. I must say I didn&#39;t like this tool at first but having come back to it, either the experience is cleaner or I have opened up a bit more.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Gist&lt;/h3&gt;&lt;a href=&quot;https://gist.github.com/&quot;&gt;https://gist.github.com/&lt;/a&gt;&lt;br /&gt;
Like &lt;a href=&quot;http://pastie.org/&quot;&gt;Pastie&lt;/a&gt; but associated to my &lt;a href=&quot;https://github.com/&quot;&gt;GitHub&lt;/a&gt; account. I&#39;m starting to use it more and more to do brain dumps of simple code snippets (e.g. PowerShell functions etc) that can be handy to reuse, but not really worth its own repo.&lt;br /&gt;
&lt;br /&gt;
If I was running an external commercial project (e.g. at home) I would seriously consider the use of &lt;a href=&quot;http://www.lowdownapp.com/&quot;&gt;LowDown&lt;/a&gt;. It fits my development style very well without the clutter and bollocks associated with other ALM/project management tools. Git integration makes it very interesting too.</description><link>http://rhysc.blogspot.com/2010/11/agile-tools-that-just-work.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-852248034225878235</guid><pubDate>Mon, 18 Oct 2010 18:37:00 +0000</pubDate><atom:updated>2010-10-18T11:37:30.288-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">nunit</category><category domain="http://www.blogger.com/atom/ns#">PowerShell</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>More AutoTesting - Powershell extensions and addins</title><description>There is a nice library called &lt;a href=&quot;http://pseventing.codeplex.com/&quot;&gt;PS-Eventing&lt;/a&gt; that makes the event handling a whole lot cleaner and generally a nicer experience. This post with the plugin is not a smaller and doesnt really do any else other than the last post except cleanly deregister the event, but is much more user friendly.&lt;br /&gt;
I think i will also post my code on gisthub as I am not and have not been at my real machine for so long... i miss it... sorry.&lt;br /&gt;
Heres the link : &lt;a href=&quot;http://gist.github.com/632749&quot;&gt;http://gist.github.com/632749&lt;/a&gt;</description><link>http://rhysc.blogspot.com/2010/10/more-autotesting-powershell-extensions.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-2042454396224388551</guid><pubDate>Wed, 13 Oct 2010 13:57:00 +0000</pubDate><atom:updated>2010-10-13T06:57:58.461-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">PowerShell</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>Auto test - Thanks Powershell</title><description>Im doing some funky Nunit stuff* at the moment and sometimes the ReSharper or TD.Net runner wont pick up my inner fixtures, the console runner however runs them just fine. Here is a PS script to have auto test running on build:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;br /&gt;
$Script:initialdir = &quot;C:\myroot\&quot;&lt;br /&gt;
&lt;br /&gt;
$fsw = new-object system.io.filesystemwatcher&lt;br /&gt;
$fsw.Path = &quot;c:\mysln\myproj\Bin\&quot;&lt;br /&gt;
$fsw.EnableRaisingEvents = $true&lt;br /&gt;
&lt;br /&gt;
$action = {&lt;br /&gt;
$filter = &quot;*Tests*.dll&quot;&lt;br /&gt;
$file = $Event.SourceEventArgs.FullPath&lt;br /&gt;
if($file -like $filter)&lt;br /&gt;
{&lt;br /&gt;
$nunit = &quot;C:\3rdParty\NUnit-2.5.2\nunit-console&quot;&lt;br /&gt;
$currentdate = get-date -format g&lt;br /&gt;
write-Host &quot;Running Tests on $file $currentdate&quot; -ForegroundColor Yellow&lt;br /&gt;
&amp;amp;&quot;$nunit&quot; /xml:$_.Name-testresult.xml $file       &lt;br /&gt;
if($LastExitCode -ne 0)&lt;br /&gt;
{&lt;br /&gt;
WRITE-HOST &quot;Test have failed for $file&quot;-ForegroundColor RED            &lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
WRITE-HOST &quot;Test have passed for $file&quot;-ForegroundColor GREEN&lt;br /&gt;
}&lt;br /&gt;
#$null = Remove-Event $_.EventIdentifier&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Register-ObjectEvent -InputObject $fsw -EventName Changed &quot;FileChanged&quot; -Action $action&lt;br /&gt;
Register-ObjectEvent -InputObject $fsw -EventName Created &quot;FileCreated&quot; -Action $action&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Note that you will either have to explicit unregister your event handlers or kill powershell to get rid of the handlers. Cancel the watcher by hitting ctrl+c and then Unregister by runnning these lines&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;br /&gt;
unregister-event &quot;FileCreated&quot;&lt;br /&gt;
unregister-event &quot;FileChanged&quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
*The stuff we are doing is to do with inheritance and inner test fixtures to give us a BDD experience without the drama of the BDD frameworks, that personally I still dont like. We are still a fair way off the TDD experience of the Ruby kids.</description><link>http://rhysc.blogspot.com/2010/10/auto-test-thanks-powershell.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-1201124941255708434</guid><pubDate>Tue, 07 Sep 2010 17:23:00 +0000</pubDate><atom:updated>2010-09-07T10:23:10.515-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">threading</category><title>Threading - I am on a Journey</title><description>Recently it has become more and more apparent that I had a crack in my understanding of a key aspect of not only the CLR but computing in general. No prizes for guessing that it was threading and the general parallel programming constructs that go along with it.&lt;br /&gt;
Now I am not a complete n00b in the threading world, I have written code that uses threads in client and server side but it was typically handing off a single task to a single thread and looking back it was probably pretty delicate and by now in need of some re-factoring love.&lt;br /&gt;
The first real kick in the pants was playing with my 8 core machine and never seeing all 8 core light up in the task manager. How&amp;nbsp;wasteful... its like all the Aston Martins I see driving over Tower Bridge; what is the point?&lt;br /&gt;
Next major trigger for me was a&amp;nbsp;computationally&amp;nbsp;heavy project that I, up until recently, was working on. My colleagues and I knew that splitting up tasks could make or break this system, however given a distinct lack of human resources and not exactly compelling hardware, time was never allocated to fleshing out the best approach.&lt;br /&gt;
Well I am no longer at that job (its somewhat unfortunate as the project could have been epic had it not be butchered by red tape and ego&#39;s) so I have had time to scrub up on my threading knowledge... well I &lt;i&gt;thought &lt;/i&gt;I would just be scrubbing up. Sometimes you just don&#39;t know how much you don&#39;t know.&lt;br /&gt;
&lt;br /&gt;
So in an attempt to short cut any one else&#39;s learning curve on the wonderful world of threading and parallel programming in the .Net world here are some great places to get started.&lt;br /&gt;
&lt;br /&gt;
As always &lt;a href=&quot;http://www.albahari.com/nutshell/&quot;&gt;C# in a Nutshell&lt;/a&gt;&amp;nbsp;is a great place to start with anything C# related. I have both 3.0 and 4.0, Joe is a great author; IMO every C# developer should have the latest copy of this book on their desk.&lt;br /&gt;
&lt;br /&gt;
Next up the deceptively good &lt;a href=&quot;http://oreilly.com/catalog/9780735627048&quot;&gt;CLR via C#&lt;/a&gt;. This book looks like its going to be as much fun as having teeth pulled out however it is&amp;nbsp;surprisingly&amp;nbsp;good and dives deep in the areas you want and would expect. I read the 2nd edition however will be buying the 3rd as soon as I can find it.&lt;br /&gt;
Obviously these books are not completely dedicated to threading but they have some great chapters dedicated to it. If you are after a more in depth reference I have been recommend Joe Duffys book : &lt;a href=&quot;http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X&quot;&gt;Concurrent Programming On Windows&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Next up is my favourite learning tool : &lt;a href=&quot;http://tekpub.com/&quot;&gt;Tekpub&lt;/a&gt;. There is a &lt;a href=&quot;http://tekpub.com/production/threading&quot;&gt;threading production under wa&lt;/a&gt;y, it only has 1 episode but it is great. As I have a yearly subscription it was a no-brainer. For me this was valuable as it has a bunch of code and a great visual comparison of auto and manual reset events, Semaphores and Mutexes. I highly recommend this video if these are confusing you at all.&lt;br /&gt;
&lt;br /&gt;
For a more casual and much briefer talk on Threading in the pre .Net 4 days check out &lt;a href=&quot;http://www.yoda.arachsys.com/csharp/threads/&quot;&gt;Jon Skeets articles &lt;/a&gt;. I have found the multiple angles these guys talk about the same topic good for bashing it into my head.&lt;br /&gt;
&lt;br /&gt;
The piece that I am currently reading is the PnP new book&amp;nbsp;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ff963553.aspx&quot;&gt;Parallel Programming with Microsoft .NET&lt;/a&gt;&amp;nbsp;that is also&amp;nbsp;available&amp;nbsp;as a hard copy book and eBook. Code snippets for the text are&amp;nbsp;available&amp;nbsp;&lt;a href=&quot;http://parallelpatterns.codeplex.com/&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The last piece that is semi related is my reading of the Manning book&amp;nbsp;&lt;a href=&quot;http://www.manning.com/petricek/&quot;&gt;Real-World Functional Programming&lt;/a&gt;. Although functional programming technically has no direct link to threading its basic tenants strongly support parallel programming and as such I have been&amp;nbsp;endeavouring&amp;nbsp;to improve my understanding and use of functional constructs where it is appropriate. So far the books is very good it is in F# and C# so it has bee a good (re)introduction to F# for me.&lt;br /&gt;
&lt;br /&gt;
With all of the movement in not only hardware (hyper-threaded and multi-core processors) as well as architectures (Grid, Cloud, ESBs etc) and the software frameworks we use (.Net&#39;s TPL, Rx etc) and how we use them (i.e the movement towards functional programming in distributed/parallel systems) I think it is becoming very clear that as .Net developers we need to know how this stuff works, how we can use it and what it means for the systems we build and the users that use them.&lt;br /&gt;
&lt;br /&gt;
As tempting as it may be to run off and just blindly use the new &lt;a href=&quot;http://blogs.msdn.com/b/pfxteam/&quot;&gt;TPL &lt;/a&gt;I strongly urge you to get a good understanding of the history and the older APM practices, I am sure this will ensure you will make better choices when you write your next parallel task.&lt;br /&gt;
As for me I&#39;m back to reading, I have a long way to go...</description><link>http://rhysc.blogspot.com/2010/09/threading-i-am-on-journey.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-1529397075279460286</guid><pubDate>Mon, 26 Jul 2010 04:55:00 +0000</pubDate><atom:updated>2010-08-03T17:29:39.366-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">asp.net</category><category domain="http://www.blogger.com/atom/ns#">linq2sql</category><category domain="http://www.blogger.com/atom/ns#">MVC</category><category domain="http://www.blogger.com/atom/ns#">NHibernate</category><title>Getting started in Asp.Net</title><description>I recently met a guy who was new to town and had picked up a job doing  development for a place that appeared to be moving towards Microsoft focused  solutions meaning he was likely to move away from his LAMP (Linux, Apache, MySQL, PHP) background  to a .Net/Sql Server environment. &lt;br /&gt;
&lt;br /&gt;
I realised after talking to him that there are a lot of ways you could go wrong coming into the .Net realm from a LAMP/Java/Python/Ruby background and this post, although intend for him, is generic enough that it may  save other web developers valuable time to get up and running, and  producing valuable software using the M$ stack&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Asp.Net&lt;/h2&gt;Asp.net is a different beast to the many other frameworks out there and you could spend years (and many have) learning all the ins and outs of the beast. &lt;br /&gt;
Dont. &lt;br /&gt;
I would highly recommend skipping WebForms all together as IMO it is a dead framework. I have been doing MS MVC for the last year and did MonoRail (an open source ASP MVC framework) on the side  prior to that and I have never looked back. Some of the significant  benefits are :&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Matches the way the web works (you explicitly work with http verbs)&lt;/li&gt;
&lt;li&gt;clean  html&lt;/li&gt;
&lt;li&gt;easy to learn&lt;/li&gt;
&lt;li&gt;pluggable&lt;/li&gt;
&lt;li&gt;testable&lt;/li&gt;
&lt;li&gt;simple&lt;/li&gt;
&lt;li&gt;And finally, IMO, encourages  better coding practices, which web forms simply does not.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
I will assume you will trust me and accept that MVC is the way forward and I will go ahead and recommend how to start.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.manning.com/palermo/&quot;&gt;Asp.Net MVC in action&lt;/a&gt; &lt;br /&gt;
First port-of-call is to pick up this book. It will give you the no BS version of the truth and covers some third party tools that will help you along the way. There is a second edition on the way however if you  are using VS 2008 then this books is for you anyway. Manning (the publisher) often have good discounts so register for emails or follow them on Twitter to know when promos are running.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://tekpub.com/production/byob&quot;&gt;TekPub : Build your own blog with MVC&lt;/a&gt;&lt;br /&gt;
Tekpub is one of my favourite resources at the moment. It is great value for money and video is an efficient way to learn new concepts. I had bought several series and now have the yearly  membership and many of my colleagues have done the same. Go check out the BYOB which shows how Rob* built a blog in  MVC. There are also MVC 2.0 and various other Asp.net series available. Buy one, buy a bunch or get a month or yearly subscription, go on, you know you want to ;)&lt;br /&gt;
*Rob was on the team that actually built Asp.net MVC&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.asp.net/mvc&quot;&gt;Asp.net&lt;/a&gt;&lt;br /&gt;
Yes the website is a good place to get lots of info too! There are lots  of little articles and videos from from smart people who live and breathe this stuff. Just be aware that there is sometimes a very Microsoft slant to the information, not a bad thing but something to be aware of. &lt;br /&gt;
&lt;br /&gt;
Next there is the Database&lt;br /&gt;
&lt;h2&gt;SQL Server&lt;/h2&gt;If you have a background in Oracle or MySql then picking up M$ Sql Server should be pretty easy. The standard practices apply e.g. dont run your web app as System Administrator. Nothing to really say here to be honest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Joining the web and data world is your data access strategy&lt;br /&gt;
&lt;h2&gt;Linq2Sql or NHibernate&lt;/h2&gt;The 2 standout choices for new commers IMO are the light weight data acess strategy from Microsfot called &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb425822.aspx&quot;&gt;Linq2Sql&lt;/a&gt; (pronounced &quot;Link to Sequel&quot;, just dont ever write it like that) or the OpenSource and more heavy weight &lt;a href=&quot;http://nhforge.org/&quot;&gt;NHibernate&lt;/a&gt;. If you are from a Java background NH may be a good tool, if you are from a Rails background then &lt;a href=&quot;http://stw.castleproject.org/Active%20Record.MainPage.ashx&quot;&gt;Castle ActiveRecord&lt;/a&gt; (which sits on tope of NH) may even be a good idea. However for most Linq2Sql is probably the best bet when you are getting started and NH is the best if you are building up more complex domains. The caveat with NH is that there is a steep learning curve. If you are new to it then check out &lt;a href=&quot;http://www.sharparchitecture.net/&quot;&gt;SharpArchitecture&lt;/a&gt; or one of the abstractions in the NHforge.com to help bootstrap yourself. If you have a simple domain or going to be building from the database up (i.e. create a database table and then the c# code to use it) Linq2Sql is a better fit anyway.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Tools&lt;/h2&gt;If you are playing with the M$ stack at home then you will most likely not want to shell out cash for the full blown enterprise versions of Visual studio and Sql Server. For this reason they have the express versions. I have only ever used the SQL express edition (which is great) so have no idea what VsExpress is like. In saying that if i did not have the full version of VS I probably would not be using .Net and just be doing rails/sinatra dev (but thats just me).&lt;br /&gt;
Assuming you are working with the full version at work then be sure to invest in the &lt;a href=&quot;http://www.jetbrains.com/resharper/&quot;&gt;Resharper&lt;/a&gt; VS plug-in. Its not super cheap but the time it will save you will mean it will quickly pay for itself.&lt;br /&gt;
&lt;br /&gt;
I terms of source control TFS is the M$ standard, but I personally don’t recommend it. I think tools like Git or even SVN are better tools that integrate better with other platforms/tools and are free. TFS however does more than source control, so if you are using make sure you use all the good ALM bug tracking bits etc&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Extra links&lt;/h2&gt;Follow the team behind the framework, most importantly &lt;a href=&quot;http://weblogs.asp.net/scottgu/&quot;&gt;Scott Gu&lt;/a&gt;  (all .net dev should read his blog)  and &lt;a href=&quot;http://www.hanselman.com/blog/&quot;&gt;Scott Hansleman&lt;/a&gt;. Mr Hanselman also  has a good &lt;a href=&quot;http://www.hanselminutes.com/&quot;&gt;podcast&lt;/a&gt; called hanselminutes that is not Asp.Net specific but a good subscription nonetheless.&lt;br /&gt;
&lt;a href=&quot;http://stackoverflow.com/&quot;&gt;StackOverflow&lt;/a&gt; is a great QnA community place for lots of developer question. The are lots of .Net and Asp.Net people hanging out here so most of your initial question will most likely have already been answered. The site itslef is even built on top of Asp.Net MVC and Linq2Sql so you can see that this combination is a very real world and scalable solution.&lt;br /&gt;
&lt;br /&gt;
If you are in Perth (like this person was) check out the &lt;a href=&quot;http://perthdotnet.org/Default.aspx&quot;&gt;Perth .Net Community of Practice&lt;/a&gt; and the  &lt;a href=&quot;http://perth.ozalt.net/&quot;&gt;Alt.Net&lt;/a&gt; lads that have monthly beers and discuss things that may or may not  be from the Microsoft mother ship that affect .Net devs.</description><link>http://rhysc.blogspot.com/2010/07/getting-started-in-aspnet.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-6123490957225380307</guid><pubDate>Thu, 24 Jun 2010 02:25:00 +0000</pubDate><atom:updated>2010-06-23T19:25:46.768-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">alt.net</category><category domain="http://www.blogger.com/atom/ns#">RavenDb</category><title>Perth Alt.Net - RavenDb</title><description>Last I did a &quot;talk&quot; on RavenDb at the Perth Alt.Net beers. I must say I was really stoked at the turn out. Lots of banter, comments, queries, theories and general discussion. I sincerely hope that everyone else enjoyed it as much as I did. I also felt that last night was moving closer to what I hope these events should be. These shouldn&#39;t be one-way dialogue. IMO the presenter is there to just start discussion and then it becomes a group affair, there should be lots of interjecting, lots of crowd participation. Last night there certainly was that and best of all it stay on track, we didn’t veer off into off-topic subjects (much) and I think the night was better for it.&lt;br /&gt;
&lt;br /&gt;
I really do feel lucky to be in the company of some very smart people and i want to thank everyone for letting me bleat on and not give me too much grief for being woefully underprepared.&lt;br /&gt;
&lt;br /&gt;
However I put it out there that the people who are comfortable enough to ask the hard questions (and there were a few), please take the reins, we want to hear from you! I’m a strong believe that you can learn as much about some from the questions they ask as the questions they answer and there were some gems last night. &lt;br /&gt;
Please contact Mike (@wolfbyte) or myself if you are thinking you may be interesting is starting a discussion, or even if you want to hear about stuff especially if it is edgy and possibly not suitable for the standard M$ .Net community of practice stream (Mitch wheat is the contact for that if you do have M$ specific stuff however). Any feedback is good. The hardest thing for organisers is trying to figure out what the crowd wants and as we nerds are not the most vocal people, making it even harder to run nerd events.&lt;br /&gt;
&lt;br /&gt;
A further incentive is we now have sponsorship. If you get up and present you get swag, swag you want. I worked out since I have been back in Perth I have received several thousand bucks worth of cool stuff from presenting or attending various .Net events. It’s worthwhile getting involved!&lt;br /&gt;
&lt;br /&gt;
Garry Stewart is up next time (in about 2 weeks) talking about light wieght IDEs, specifically VIm and letting go of our addiction that is Visual Studio.&lt;br /&gt;
&lt;br /&gt;
One big note I also want to make. Take the talks for what they are. The whole under current of Alt.Net is &quot;options&quot;. We need to be aware there are options. We are not saying you must throw away SQL and use RavenDB exclusively or Vi will replace Studio, we just want people to open their minds. If last nights talk got you thinking about how you could get you python web stck talking to cassandra, sweet, most of what we are talking about is concepts, if there is a tool involved, its just there because it facilitates a different way of thinking. Thats all.&lt;br /&gt;
&lt;br /&gt;
See you next time :)</description><link>http://rhysc.blogspot.com/2010/06/perth-altnet-ravendb.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-131127927258773928</guid><pubDate>Thu, 17 Jun 2010 04:07:00 +0000</pubDate><atom:updated>2010-06-16T21:07:03.063-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">DDD</category><title>DDD eXchange 2010 - London</title><description>Un fortunately i dio not attend this event (which looked like an awesome event) however the Skills matter guys were good enough to post the videos of the event... sweeet!&lt;br /&gt;
&lt;br /&gt;
DDD EXCHANGE 2010 - PODCASTS, SLIDES AND PICTURES&lt;br /&gt;
&lt;br /&gt;
Thye have recorded all the DDD eXchange 2010 talks. The slides and podcasts can be viewed here:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://skillsmatter.com/podcast/design-architecture/keynoteddd-emerging-themes-2010/zx-974&quot; target=&quot;_blank&quot;&gt;Keynote: DDD Emerging Themes of 2010 (Eric Evans)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://skillsmatter.com/podcast/design-architecture/architectural-innovation-cqrs/zx-974&quot; target=&quot;_blank&quot;&gt;Architectural Innovation: CQRS (Udi Dahan)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://skillsmatter.com/podcast/design-architecture/architectural-innovation-eventing-event-sourcing/zx-974&quot; target=&quot;_blank&quot;&gt;Architectural Innovation: Eventing, Event Sourcing (Greg Young)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://skillsmatter.com/podcast/design-architecture/parkbench-panel-discussion-1008/zx-974&quot; target=&quot;_blank&quot;&gt;The 1st Parkbench Panel Discussion&lt;br /&gt;
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://skillsmatter.com/podcast/design-architecture/ddd-revelations-and-misunderstandings-a-report-from-the-trenches/zx-974&quot; target=&quot;_blank&quot;&gt;DDD Revelations and Misunderstanding: A Report from the Trenches (Ian Cooper)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://skillsmatter.com/podcast/design-architecture/ddd-tdd-bdd/zx-974&quot; target=&quot;_blank&quot;&gt;DDD, TDD, BDD (Gojko Adzic)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://skillsmatter.com/podcast/design-architecture/folding-together-ddd-agile/zx-974&quot; target=&quot;_blank&quot;&gt;Folding Together DDD &amp;amp; Agile (Eric Evans)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://skillsmatter.com/podcast/design-architecture/parkbench-panel-discussion-1013/zx-974&quot; target=&quot;_blank&quot;&gt;The 2nd Parkbench Panel Discussion&lt;br /&gt;
&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;You can also find some photos taken at the conference &lt;a href=&quot;http://skillsmatter.com/event/design-architecture/ddd-exchange-2010/zx-974&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thanks SkillsMatter!</description><link>http://rhysc.blogspot.com/2010/06/ddd-exchange-2010-london.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-9184958998657864250</guid><pubDate>Fri, 11 Jun 2010 02:32:00 +0000</pubDate><atom:updated>2010-06-10T20:14:16.135-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">DDD</category><category domain="http://www.blogger.com/atom/ns#">Testing</category><title>Test Fakes - Solving a Domain Entity Issue</title><description>Follow on from :&lt;a href=&quot;http://rhysc.blogspot.com/2010/04/testing-with-domian-driven-design.html&quot;&gt;Testing with Domain Driven Design&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;Background on the design in question&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;We are using NHibernate for persistence on Oracle.&lt;/li&gt;
&lt;li&gt;We have service that accept command that are coarse grained and perform a clearly defined business function, they are not chatty services.&lt;/li&gt;
&lt;li&gt;We are using the notion of aggregate roots so all child objects are created and managed by the owning aggregate root. If you need to access the child it must be done via the AR&lt;/li&gt;
&lt;li&gt;The domain is relatively large and complex.&lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt;Background problem&lt;/h4&gt;&lt;p&gt;We had issues where we were dealing with domain objects in test and getting problems with interrogating child collections. For example we sometimes need to be able to update a child of an aggregate root and we were using the id of the child (within our command object) to indicate which child to update. We are using a basic database identity field (oracle sequence) for setting the ids on all of our user defined entities.&lt;br /&gt;
Herein lies our problem;* In our test we create an aggregate root complete with child objects. We then want to test, for example, updating a child of the aggregate root via a DTO based command (i.e. using an id to define the child to update) and we run into issues when all of the child object have the same id of 0 as they are not persisted (it’s a unit test). Now this would never happen in real life. Why would you issue a command to update something that has not been persisted, how do you even know about that object?&lt;br /&gt;
The quick solution that I have seen used a lot is to set the ids of all of the domain objects prior to running the test. I don’t like this if you are doing this by exposing the ID setter on the domain object. This is opening up the API of our domain for testability and is potentially the start of a slippery slope in to a pit of hell. An easy way around this is to use fakes. These object are just child object of the domain objects in question that help expose stuff the domain shouldn’t; in this case the ID setter.&lt;br /&gt;
The other alternative is to set the id on creation of the fake so the setter of the id is not exposed. This can also work but it will mean your fake will always have an id set. For the situation I was in this was not suitable.&lt;br /&gt;
&lt;/p&gt;&lt;h4&gt;The end solution&lt;/h4&gt;&lt;p&gt;All domain objects have a fake create for it. All of the fake implement an interface ISettableId&lt;tid&gt;. This interface is defined as below:&lt;br /&gt;
&lt;/p&gt;**CODE GOES HERE**&lt;br /&gt;
&lt;pre&gt;public interface ISettableId&lt;tid&gt;
{
    bool HasIdBeenSet();
    void SetId(TId id);
}&lt;/pre&gt;&lt;br /&gt;
With an implementation example (its id type is and integer) :&lt;br /&gt;
&lt;pre&gt;public class FooFake : Foo, ISettableId&lt;int&gt;
{
    public FooFake(string name, TypeRequiredForValidConstruction myDependecy)
    : base(name, myDependecy)
    {}
    public bool HasIdBeenSet()
    {
        return _id != 0;
    }
    public void SetId(int id)
    {
        _id = id;
    }
}&lt;/pre&gt;&lt;p&gt;This mean we can now create fake objects and emulate persistence later by reflecting down the object graph and setting all of the ids. This is much faster than hitting the database and has proved to be a very valid exercise as we can now run tests again transient and persisted versions of the object graph without having a db connection.&lt;br /&gt;
One additional thing I should mention is that the creation of child object now must be exposed as a hook. For example when we create child objects I do not just new up to object and add it to a collection. I call a protected virtual method that creates the child object and then add that to the list. This allows my fake to override the return type that is added to the list so children can also be fakes. This has not increased the exposure of the domain but has now facilitate a hook to allow me to create fakes for my child collection.&lt;/p&gt;&lt;h4&gt;Caveats:&lt;/h4&gt;&lt;p&gt;Fakes should not include any logic. The fakes I am using only allow the setting of ids. The only logic they have is to check whether the id is set (this allows us to skip objects that have had their ids set when we walk the object graph and not go around in circles). The only other methods that are required is the overrides of the creation of child objects.&lt;br /&gt;
Other methods you may find in the fakes are builder methods. Instead of having big factories for creating test object you may choose to put the object creation closer to the owner by putting it in the fake class itself.&lt;br /&gt;
&lt;/p&gt;&lt;h4&gt;Summary&lt;/h4&gt;&lt;p&gt;As I mentioned, we have a pretty large and complex domain we were running into issues where the difference between persisted and non persisted objects graphs was becoming problematic; using the fakes has allowed us to keep the domain clean and only as open as possible while allowing us to emulate persistence without the cost of hitting a database. Over all I’m pretty happy with the result.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
*I’m sure there are other way to solve this higher level problem</description><link>http://rhysc.blogspot.com/2010/06/test-fakes-solving-domian-entity-issue.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-6632632073970921622</guid><pubDate>Thu, 27 May 2010 07:44:00 +0000</pubDate><atom:updated>2010-05-27T00:44:10.235-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">alt.net</category><category domain="http://www.blogger.com/atom/ns#">openspaces</category><title>Alt.Net, Openspaces, whatever its coming...</title><description>Google groups and Twitter has been busy today after I seemed to have started some hype about an Alt.Net styled openspaces event (#ozopenspace)&lt;br /&gt;
&lt;br /&gt;
PLEASE spread the word. We need ideas when people can come and where they would go to (Australia is a big place, we are all very spread out)&lt;br /&gt;
&lt;br /&gt;
The wiki looks like its going to be based  here: &lt;a href=&quot;http://ozopenspace.pbworks.com/&quot;&gt;http://ozopenspace.pbworks.com&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Register you interest &lt;a href=&quot;http://ozopenspace.pbworks.com/expressions-of-interest&quot;&gt;here.&lt;/a&gt; Seriously please do this otherwise we can not estimate or cater for your needs/wants etc. This will also show sponsors if we are serious or not and may help convince overseas guest to attend too, of which there is already interest :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The discussion is on the oz alt.net google groups &lt;a href=&quot;http://groups.google.com/group/ozaltdotnet/browse_thread/thread/d3a8eaeeb019babb&quot;&gt;here&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I cant wait!</description><link>http://rhysc.blogspot.com/2010/05/altnet-openspaces-whatever-its-coming.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-1967113630163250876</guid><pubDate>Wed, 26 May 2010 15:16:00 +0000</pubDate><atom:updated>2010-05-26T16:28:29.175-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Google Maps</category><category domain="http://www.blogger.com/atom/ns#">PowerShell</category><category domain="http://www.blogger.com/atom/ns#">Web Services</category><title>Powershell and the web</title><description>Lately I have been playing with PowerShell to see if it can help with some uptime/availability checks for our web sites and services at work; Yes i know what you are thinking but I&#39;m not a sys-admin and I need to know if my stuff is working with out having access to the server... long story I&#39;m sure you will appreciate.&lt;br /&gt;
&lt;br /&gt;
In my reading I have seen lots of flaky posts about PowerShell and web services. I think people need to remember that web services still conform to the http protocol, there is no magic, you do not need to access any visual studio dll or do any weird crap like that, you just need to hit the url and receive a payload.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
    $wc = new-object system.net.WebClient
    $webpage = $wc.DownloadData($url)     
&lt;/pre&gt;&lt;br /&gt;
That&#39;s it. No weird proxies no importing custom dll&#39;s.&lt;br /&gt;
&lt;br /&gt;
Here&#39;s an example calling the Google Maps API (which is a nice API BTW) to get a latitude and longitude of an address, specifically Perth&#39;s craziest bar &lt;a href=&quot;http://www.devillespad.com/&quot;&gt;Devilles Pad&lt;/a&gt; (think Satan living in a trailer park that hangs out at a Go-Go club that used to be a James Bond-villians liar, yeah its that cool:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
    $url = &quot;http://maps.google.com/maps/api/geocode/xml?address=3+Aberdeen+St,+Perth,+WA+6000,+Australia&amp;amp;sensor=false&quot;
    $wc = new-object system.net.WebClient
    $webpage = $wc.DownloadString($url)#Edit -Thanks Ken
    $xmldata = [xml]$webpage
    $lat = $xmldata.GeocodeResponse.result.geometry.location.lat
    $lng = $xmldata.GeocodeResponse.result.geometry.location.lng
    write-host &quot;Latitude = $lat - Longitude = $lng&quot; 
&lt;/pre&gt;&lt;br /&gt;
Like that? Go play: &lt;a href=&quot;http://code.google.com/apis/maps/documentation/geocoding/&quot;&gt;Google Maps API Doco&lt;/a&gt;</description><link>http://rhysc.blogspot.com/2010/05/powershell-and-web.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-8046342963331950516</guid><pubDate>Fri, 07 May 2010 08:40:00 +0000</pubDate><atom:updated>2010-05-07T07:00:52.828-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Continuous Integration</category><category domain="http://www.blogger.com/atom/ns#">MSBuild</category><title>MSBuild 101</title><description>&lt;div class=&quot;MsoNormal&quot;&gt;Lately for some reason I have seen a fair bit of tension around MSBuild. I guess this is good thing, more people are using build tools like PSake, Rake etc and most of the time if you are building .Net stuff sooner or later you will have to call into MSBuild, unless your feel bold enough to uses csc... um... not for me.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
MSBuild is, to be honest, very basic.&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;There are typical 2 things that I use MSBuild for&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;-Defining a build script&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;-Running a build&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
The term MSBuild is a little confusing to some as its covers a few things: a file type and an executable.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Firstly we need to be aware that all .Net solution files (*.sln) and project files (*.*proj) files in .Net are MSBuild files; that should hopefully ease some tension as it is now pretty obvious that you are already using MSBuild! The MSBuild files are XML and therefore human readable and modifiable. The files typically define properties and tasks. The properties can reference other properties and they can be collections too. The tasks can have dependencies on other task (i.e. Test requires Build which requires Clean) and the task can make use of our properties we have defined in our script as well as define items that are basically task level variables. This is starting to sound just like procedural programming, which I hope we are all au fait with. It is probably also a good time to note that pretty much all build tools use the notion of dependencies. This basically means if you call a task and it has a dependant task then that task will be called first. You can have chained dependencies like the example we mentioned before (i.e. Test requires Build which requires Clean) and you can also have multiple dependencies for one given task (Deploy Requires Package, Document, Test).&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
After reading that it is quite clear that MSBuild is actually very simple. It is the syntax and general XML noise that scares most people, including myself.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;h2&gt;Running MSBuild&lt;o:p&gt;&lt;/o:p&gt;&lt;/h2&gt;&lt;div class=&quot;MsoNormal&quot;&gt;To achieve the most trivial usage out of MSBuild we need to know how the executable works so we can actually call MSBuild to do something. MSBuild comes with Visual studio, I don’t think it actually comes with the .Net framework (someone can correct me here) and it is also bound to a framework version. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
To start with I will show the most trivial example of how to use MSBuild and that is to just build a solution.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;@C:\Windows\Microsoft.NET\Framework\v3.5\MSbuild.exe MySolution.sln&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
Assuming that this command is run in the directory that MySolution.sln resides this will build that solution. It can’t get much easier than that. Note this will not do anything clever, it will just build to your default location ie bin/debug for each project in the solution. Personally for me this offers little value other than it is a bit faster than building in visual studio.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
Typically if I am building using the command line it is because I am building from a build tool. Build tools like PSake allow me a lot more flexibility as they are not constrained by the bounds of XML and have powerful functions I can use that may be associated to builds and deployments that might not otherwise exist in MSBuild. If you are using a tool like PSake or Rake as your build script then it is more likely that you will use the following syntax:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&amp;amp;$msbuild &quot;$solution_file&quot; /verbosity:minimal /p:Configuration=&quot;Release&quot; /p:Platform=&quot;Any CPU&quot; /p:OutDir=&quot;$build_directory&quot;\\&amp;nbsp; /logger:&quot;FileLogger,Microsoft.Build.Engine;logfile=Compile.log&quot;&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
This is from a PSake script so anything with a $ in front of it is a PowerShell variable (i.e. not MSBuild syntax). Walking through this I have defined the location of the MSBuild exe ($msbuild) and the sln file. Note that the sln file is note associated to a switch. It is the first argument and this indicates that this is the file we are building. Other arguments are prefixed with a switch. These switches begin with a forward slash and end in a colon and contain either full descriptive words (e.g. &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;/verbosity:minimal&lt;/span&gt;) or short hand syntax for a word (e.g. &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;/p:Platform=&quot;Any CPU&quot; &lt;/span&gt;which is short for property and in this example defines the platform property)&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
FYI : The &amp;amp; at the start of the line is a PowerShell construct to say &quot;run this command, don’t just print it to the screen&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;h2&gt;Defining Build Scripts with MSBuild&lt;o:p&gt;&lt;/o:p&gt;&lt;/h2&gt;&lt;div class=&quot;MsoNormal&quot;&gt;First up we will walk through a very basic build script that justs cleans and builds a solutions. It will be pretty obvious that this scripts really offers little value but we will get to some of the nitty gritty stuff soon.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Project&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;DefaultTargets&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Clean&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;xmlns&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;ToolsVersion&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;3.5&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Import&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Project&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;PropertyGroup&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ApplicationName&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;MySolution&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;color: #a31515;&quot;&gt;ApplicationName&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;SolutionFile&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;..\$(ApplicationName).sln&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;color: #a31515;&quot;&gt;SolutionFile&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;PropertyGroup&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Clean&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;MSBuild&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Targets&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Clean&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;Projects&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(SolutionFile)&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Build&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;DependsOnTargets&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Clean;&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;MSBuild&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Targets&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Rebuild&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;Projects&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(SolutionFile)&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;Properties&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Configuration=Release;&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Project&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;,&amp;quot;serif&amp;quot;; font-size: 12pt;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
Let’s go over this line by significant line:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;The xml documents root is the project where we define the xml namespace, the MSBuild Tools version and the default target. Make sure you tools version work with your .Net framework version. This first line is pretty standard for me. I like having a default target and im typically working with .net 3.5 at the moment so this is all good.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Next up we are importing an external extension. This is an example of importing the very useful MSBuild Community Extension toolset. If you are making use of MSBuild a lot then you will want this toolset. Another Import I often make is for Gallio a very handy test runner. Please note that this import demonstrated is not being used in the script so could safely be removed, it is just here to show the syntax&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Next we define our property group section. The nodes in here are user defined. MSBuild does not have “ApplicationName in its schema, i made that name up. These properties are in effect you global variables. You will also note that you can reference other Properties from with properties as shown in the solution file property. This is often very handy when dealing with file paths. Then Syntax for referencing a single properties is $(MyProperty)&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Next up we define our first target. Targets are just like methods in that they define functionality. The Clean target just calls an MSBuild task that cleans the solution. Not very impressive, I know. The next target shows how we can specify dependencies. This means any time we call the Build target the Clean target must run first.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
Having a build file is all very nice but we need to be able to run it. As it is not a solution of project file I tend to treat them a little different to how I would call those files directly. I typically prefer to be explicit in calling target, even though it is a DRY violation. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
I have an example extracted from a bat file that calls into an MSBuild script below to show you the syntax (this is the same syntax as if you were to run from the cmd line):&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;@C:\Windows\Microsoft.NET\Framework\v3.5\MSbuild.exe MyMSBuildFile.build /t:UnitTests /l:FileLogger,Microsoft.Build.Engine;logfile=&quot;UnitTests.log&quot;&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
From this you can see:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraphCxSpFirst&quot;&gt;-I am calling MSBuild 3.5; MSBuild is slight different for each .Net version, be sure you are not calling the .Net 2 version for your&amp;nbsp;new shiny .Net 4 solutions!&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraphCxSpMiddle&quot;&gt;-MyMSbuildFile.build is in the location I am running this command. If it was not I would need a relative or full path.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraphCxSpMiddle&quot;&gt;-The extension of an MSBuild script is not important. I personally prefer to call my MSBuild files *.build to make it clear that they are in fact build scripts&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraphCxSpMiddle&quot;&gt;-The &quot;/t:&quot; switch defines the target I am calling: UnitTest. You do not need to specify this if you have defined the Initial Target in the project tag in you build file. I recommend defining a default target and make sure it is a safe one... you don’t want to accidently deploy something to production &quot;by default&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraphCxSpLast&quot;&gt;-By using the &quot;/l:&quot; switch I can define a logger so I don’t lose the info once the console window disappears. I pretty much only use this syntax and change the name of the output file.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&amp;nbsp;For more help you can just call the MSBuild exe and use the /? for a detail example of what the exe can do. I recommend doing this :)&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Stepping Up&lt;o:p&gt;&lt;/o:p&gt;&lt;/h2&gt;&lt;div class=&quot;MsoNormal&quot;&gt;So everything I have shown you so far is all well and good but it is of little value in the real world. So here is a quick fire list of problem and MSBuild solutions, a cheat sheet of sorts:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Note the command line syntax used below is from PowerShell and to get the MSBuild variable assigned I have called:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: small; line-height: 115%;&quot;&gt;[System.Reflection.Assembly]::Load(&#39;Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&#39;) | Out-Null&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&amp;nbsp;$msbuild = [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFrameworkFile(&quot;msbuild.exe&quot;, &quot;VersionLatest&quot;)&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;h3&gt;Change a property from outside the script&lt;o:p&gt;&lt;/o:p&gt;&lt;/h3&gt;&lt;div class=&quot;MsoNormal&quot;&gt;You have a property, say application name defined in a script, you want to reuse the script but not have to edit the script for everything that uses it. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Solution : use the property switch &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&amp;amp;$msbuild &quot;$build_file&quot; /p:ApplicationName=&quot;RhysCNewApp&quot;&lt;/span&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;h3&gt;Directories with spaces are failing when passing them to MSBuild&lt;o:p&gt;&lt;/o:p&gt;&lt;/h3&gt;&lt;div class=&quot;MsoNormal&quot;&gt;If you are passing in paths from a build tool that requires you to use quote (e.g. the path has spaces in it) then MSBuild may throw its toys and blow up on you. To dodge this use double backslashes (\\) at the end of the argument to escape the nastiness that is MSBuild&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;amp;$msbuild &quot;$solution_file&quot; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;/p:OutDir=&quot;c:\Rhys Hates Spaces\In His\ Directory Paths\&quot;\\&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;&lt;h2&gt;Inside your Scripts&lt;o:p&gt;&lt;/o:p&gt;&lt;/h2&gt;&lt;h3&gt;Display a message to the console&lt;o:p&gt;&lt;/o:p&gt;&lt;/h3&gt;&lt;div class=&quot;MsoNormal&quot;&gt;I want to display the paths of my Visual Studio tools folder for ‘05 and ‘08. Note VS80COMNTOOLS and VS90COMNTOOLS are environment variable, so yeah MSBuild can pick those up too &lt;span style=&quot;font-family: Wingdings;&quot;&gt;J&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;VS&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Message&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Text&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;***********$(VS80COMNTOOLS)***********&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Message&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Text&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;***********$(VS90COMNTOOLS)***********&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;h3&gt;I want to reference a whole Item group&lt;o:p&gt;&lt;/o:p&gt;&lt;/h3&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Sometimes we have collections of related items and want to reference all of those items:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ItemGroup&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Items&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Include&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Foo&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Items&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Include&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Bar&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Items&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Include&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Baz&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ItemGroup&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Message&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Message&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Text&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;@(Items)&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; /&amp;gt;&amp;nbsp;&amp;nbsp; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;This will produce: &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Foo;Bar;Baz&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;h3&gt;I want a conditional execution&lt;o:p&gt;&lt;/o:p&gt;&lt;/h3&gt;&lt;div class=&quot;MsoNormal&quot;&gt;I want to delete a folder, but only if it exists&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Clean&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;RemoveDir&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Directories&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(OutputDirectory)&lt;/span&gt;&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Condition&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Exists($(OutputDirectory))&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;RemoveDir&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;This show the use of Exists() and the MSBuild command RemoveDir.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;h3&gt;Error Messages&lt;o:p&gt;&lt;/o:p&gt;&lt;/h3&gt;&lt;div class=&quot;MsoNormal&quot;&gt;I want to display a meaningful error when an exception should be raised in my task. Solution use the Error command within you task&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;UnitTests&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;DependsOnTargets&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Build&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Gallio&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Assemblies&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;@(UnitTestProject)&lt;/span&gt;&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;IgnoreFailures&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;true&lt;/span&gt;&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;EchoResults&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;true&lt;/span&gt;&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ReportDirectory&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(ReportOutputDirectory)&lt;/span&gt;&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ReportTypes&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(ReportTypes)&lt;/span&gt;&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;RunnerType&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(TestRunnerType)&lt;/span&gt;&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ShowReports&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(ShowReports)&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Output&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;TaskParameter&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;ExitCode&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;PropertyName&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;ExitCode&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Gallio&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Error&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Text&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;Tests execution failed&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;Condition&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&#39;$(ExitCode)&#39; != 0&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;This examples show the use of the Gallio MSBuild task and how we can raises an error if the exit code is not 0 was the command is run&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;h3&gt;Conditional Properties&lt;o:p&gt;&lt;/o:p&gt;&lt;/h3&gt;&lt;div class=&quot;MsoNormal&quot;&gt;I want properties to have value dependant on conditions:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;PropertyGroup&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ReportTypes&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Condition&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&#39;$(ReportTypes)&#39;==&#39;&#39;&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Html-Condensed&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ReportTypes&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;PropertyGroup&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Swap out Configuration files&lt;o:p&gt;&lt;/o:p&gt;&lt;/h3&gt;&lt;div class=&quot;MsoNormal&quot;&gt;This is last as it is a personal preference on how to manage environmental differences. I basically have all my configuration files in one directory and have N+1 files per file type where N is the number of environments. I may have a ConnectionString.Config and right next to it will be ConnectionString.Config.DEV, ConnectionString.Config.TEST, ConnectionString.Config.UAT, ConnectionString.Config.PROD with each environments values in the respective file. My build only acknowledges the ConnectionString.Config file and it copies that one, the rest are not included in the build. So when i build for an environment I swap out the config files as part of the build. A contrived example of how to do this is below:&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Name&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;SetDevConfigFiles&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ItemGroup&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;SourceFiles&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Include&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(ApplicationConfigFolder)\*.Dev&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;ItemGroup&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Copy&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;SourceFiles&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;@(SourceFiles)&lt;/span&gt;&quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&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=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;DestinationFiles&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;@(SourceFiles-&amp;gt;&#39;$(ApplicationConfigFolder)\%(Filename)&#39;)&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;This grabs all of the files from the Application Config Folder that end in .DEV and copies them to the same location without the DEV. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Explaination: The %(Filename) means I get the filename with out the extension. MSBuild basially just removes anything after the last “.” in the file name, this means I over write ConnectionString.Config with the contents from ConnectionString.Config.DEV. Its handy, it works for me, take it or leave it.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;h2&gt;Creating your own MSBuild Task&lt;o:p&gt;&lt;/o:p&gt;&lt;/h2&gt;&lt;div class=&quot;MsoNormal&quot;&gt;This was way easier than I thought it was going to be. To create a task you just need to inherit from Microsoft.Build.Utilities.Task, override the execute method and add some properties. Here is a SQL migration build task I built (please excuse the logging and the IoC Cruft). The code to do all the leg work was already done and it had a console to fire it up. At the time I was using MSBuild to call it and i was using the exec functionality of MSBuild when I thought: I could probably just make a plug in for this! Below is the result &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;using&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; System;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;using&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; Microsoft.Build.Framework;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;using&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; Microsoft.Build.Utilities;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;using&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; Microsoft.Practices.ServiceLocation;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; SqlVersionMigration.MsBuildTask&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af;&quot;&gt;RunAllScripts&lt;/span&gt; : &lt;span style=&quot;color: #2b91af;&quot;&gt;Task&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style=&quot;color: #2b91af;&quot;&gt;Required&lt;/span&gt;]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; ScriptLocation { &lt;span style=&quot;color: blue;&quot;&gt;get&lt;/span&gt;; &lt;span style=&quot;color: blue;&quot;&gt;set&lt;/span&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style=&quot;color: #2b91af;&quot;&gt;Required&lt;/span&gt;]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; ConnectionString { &lt;span style=&quot;color: blue;&quot;&gt;get&lt;/span&gt;; &lt;span style=&quot;color: blue;&quot;&gt;set&lt;/span&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;bool&lt;/span&gt; Execute()&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;try&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: #2b91af;&quot;&gt;ContainerRegistration&lt;/span&gt;.Init();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; versionMigrationService = &lt;span style=&quot;color: #2b91af;&quot;&gt;ServiceLocator&lt;/span&gt;.Current.GetInstance&amp;lt;&lt;span style=&quot;color: #2b91af;&quot;&gt;VersionMigrationService&lt;/span&gt;&amp;gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: #2b91af;&quot;&gt;TaskHelper&lt;/span&gt;.LogEntry(Log, ScriptLocation, ConnectionString);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; result = versionMigrationService.RunAllScriptsInOrder(ConnectionString, ScriptLocation);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #2b91af;&quot;&gt;TaskHelper&lt;/span&gt;.LogResult(Log, result);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;return&lt;/span&gt; !result.Isfailed;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;catch&lt;/span&gt; (&lt;span style=&quot;color: #2b91af;&quot;&gt;Exception&lt;/span&gt; ex)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: #2b91af;&quot;&gt;TaskHelper&lt;/span&gt;.LogError(Log, ex);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;false&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;h2&gt;Some hints to get the most out of MSBuild:&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/h2&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Download the MSBuild Community extensions, there is lots of good stuff here.&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Use plugins where it is a logical idea as opposed to calling out to exes. This can be done by using the import tag at the start of your file:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0.0001pt;&quot;&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Import&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;Project&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;&quot;&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets&lt;/span&gt;&quot;&lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;Know when to use MSBuild. It is a good starting point if you are learning about automated builds, especially as you have to use it every day (if you are a .Net dev) whether you like it or not (remember all sln and proj file are MSBuild files). Be warned though that it is not really the best option for stuff out side of a pure build. Once you are comfortable with MSBuild you will soon hit a very low ceiling. At that point investigate other tools like PSake and Rake. Due to the XML nature of MSBuild certain task are just messy or impossible to perform; Loops is a good example, just don’t do it.&lt;br /&gt;
&lt;br /&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
I hope that is enough to get you up and running, if not let me know and I will try to fill in any of the gaps&lt;/div&gt;</description><link>http://rhysc.blogspot.com/2010/05/msbuild-101.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-7104591833850777107</guid><pubDate>Tue, 27 Apr 2010 15:36:00 +0000</pubDate><atom:updated>2010-04-27T08:36:39.901-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Castle</category><title>Castle - Reborn!</title><description>It looks like Castle has had a shake up! I don&#39;t *know* who is behind all this but I know my my castle &lt;a href=&quot;http://kozmic.pl/&quot;&gt;go-to-guy&lt;/a&gt; has his sticky fingers in it and I&#39;m glad he does!&lt;br /&gt;
Of late there is a new Castle Wiki and thanks to &lt;a href=&quot;http://andypike.wordpress.com/&quot;&gt;Andy Pike&lt;/a&gt; a bunch of new screen cast dedicated to&amp;nbsp; getting up and running with the various aspect of the Castle framework.&lt;br /&gt;
&lt;br /&gt;
So the links are:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://castleproject.org/&quot;&gt;Current site&lt;/a&gt; which may get replaced in the future &lt;/li&gt;
&lt;li&gt;New &lt;a href=&quot;http://stw.castleproject.org/&quot;&gt;Castle wiki&lt;/a&gt; and general go to place &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://castlecasts.com/&quot;&gt;&lt;span class=&quot;goog-spellcheck-word&quot; style=&quot;background: none repeat scroll 0% 0% yellow;&quot;&gt;CastleCasts&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;Please check them out and if you want to add anything i have been told that the wiki is a real wiki, so contribute!&lt;br /&gt;
Thanks to &lt;span class=&quot;goog-spellcheck-word&quot; style=&quot;background: none repeat scroll 0% 0% yellow;&quot;&gt;Krzysztof&lt;/span&gt; &lt;span class=&quot;goog-spellcheck-word&quot; style=&quot;background: none repeat scroll 0% 0% yellow;&quot;&gt;Koźmic&lt;/span&gt; for the heads up :)&lt;br /&gt;
&lt;br /&gt;
*OK so Castle is not reborn, just the &lt;span class=&quot;goog-spellcheck-word&quot; style=&quot;background: none repeat scroll 0% 0% yellow;&quot;&gt;doco&lt;/span&gt; ;)</description><link>http://rhysc.blogspot.com/2010/04/castle-reborn.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-8077582001917734908</guid><pubDate>Tue, 27 Apr 2010 15:06:00 +0000</pubDate><atom:updated>2010-04-27T08:06:41.228-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">NHibernate</category><title>Soft Deletes in Nhibernate</title><description>The following was an email to my dev colleagues, sorry about the code formatting Im using the Blogger web interface (OSX really needs a WLW equivlient!):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fellow nerds;&lt;br /&gt;
There are frequently requirements that we need to have soft deletes. These things are a pain, especially with an ORM as they can start becoming invasive to your domain code.&lt;br /&gt;
&lt;br /&gt;
If you want soft deletes to be transparent as possibly in normal workings of the domain you can use a DeleteListener to intercept the deletion and, well, soften it.&lt;br /&gt;
Below is some code to show a parent and child relationship (ParentSampleDomainObject and SampleDomainObject).&lt;br /&gt;
&lt;br /&gt;
Key points:&lt;br /&gt;
• The entities need to have a flag to show they are deleted eg IsDeleted&lt;br /&gt;
• The mapping on the parent needs to say that it is not interested in retrieving deleted items by using a where clause&lt;br /&gt;
• The mapping also need to say it want to delete orphan children, (we won’t actually delete them, but this needs to be here)&lt;br /&gt;
• We need to have an NHibernate delete listener to intercept the cascading delete and instead of deleting the entity mark it as deleted. This is why we need cascading deletes in the mapping&lt;br /&gt;
• We need to register the listener to the config.&lt;br /&gt;
&lt;br /&gt;
The test code will be checked into the core soon.&lt;br /&gt;
&lt;br /&gt;
Rhys&lt;br /&gt;
&lt;br /&gt;
Nhibernate Configuration:&lt;br /&gt;
&lt;pre&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;hibernate-configuration xmlns=&quot;urn:nhibernate-configuration-2.2&quot;&amp;gt;
    &amp;lt;session-factory name=&quot;applicationregister&quot;&amp;gt;
        &amp;lt;property name=&quot;dialect&quot;&amp;gt;NHibernate.Dialect.MsSql2005Dialect&amp;lt;/property&amp;gt;
        &amp;lt;property name=&quot;connection.provider&quot;&amp;gt;NHibernate.Connection.DriverConnectionProvider&amp;lt;/property&amp;gt;
        &amp;lt;property name=&quot;connection.driver_class&quot;&amp;gt;NHibernate.Driver.SqlClientDriver&amp;lt;/property&amp;gt;
        &amp;lt;property name=&quot;proxyfactory.factory_class&quot;&amp;gt;NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle&amp;lt;/property&amp;gt;
        &amp;lt;property name=&quot;connection.connection_string&quot;&amp;gt;Data Source=.\SqlExpress;Database=CoreTests;Integrated Security=True;&amp;lt;/property&amp;gt;
        &amp;lt;property name=&quot;connection.isolation&quot;&amp;gt;ReadCommitted&amp;lt;/property&amp;gt;
        &amp;lt;property name=&quot;default_schema&quot;&amp;gt;CoreTests.dbo&amp;lt;/property&amp;gt;
        &amp;lt;mapping assembly=&quot;RhysC.NHibernate.Tests&quot;/&amp;gt;
        &amp;lt;event type=&quot;save-update&quot;&amp;gt;
            &amp;lt;listener class=&quot;RhysC.NHibernate.AuditListener,RhysC.NHibernate&quot;/&amp;gt;
        &amp;lt;/event&amp;gt;
        &amp;lt;event type=&quot;save&quot;&amp;gt;
            &amp;lt;listener class=&quot;RhysC.NHibernate.AuditListener,RhysC.NHibernate&quot;/&amp;gt;
        &amp;lt;/event&amp;gt;
        &amp;lt;event type=&quot;delete&quot;&amp;gt;
            &amp;lt;listener class=&quot;RhysC.NHibernate.SoftDeleteListener,RhysC.NHibernate&quot;/&amp;gt;
        &amp;lt;/event&amp;gt;
    &amp;lt;/session-factory&amp;gt;
&amp;lt;/hibernate-configuration&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Parent Domain entities mapping file:&lt;br /&gt;
&lt;pre&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;hibernate-mapping xmlns=&quot;urn:nhibernate-mapping-2.2&quot; namespace=&quot;NHibernate.Tests&quot; assembly=&quot;NHibernate.Tests&quot;&amp;gt;
    &amp;lt;class name=&quot;ParentSampleDomainObject&quot; table=&quot;ParentSampleDomainObject&quot;&amp;gt;
        &amp;lt;id name=&quot;Id&quot; column=&quot;ParentSampleDomainObjectId&quot;&amp;gt;
            &amp;lt;generator class=&quot;identity&quot;/&amp;gt;
        &amp;lt;/id&amp;gt;
        &amp;lt;bag name=&quot;Children&quot; inverse=&quot;true&quot; lazy=&quot;true&quot; cascade=&quot;all-delete-orphan&quot; where=&quot;IsDeleted = 0&quot;&amp;gt;
            &amp;lt;key column=&quot;ParentSampleDomainObjectId&quot; foreign-key=&quot;ParentSampleDomainObjectId_FK&quot;/&amp;gt;
            &amp;lt;one-to-many class=&quot;SampleDomainObject&quot;/&amp;gt;
        &amp;lt;/bag&amp;gt;
    &amp;lt;/class&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;[&lt;span style=&quot;color: #2b91af;&quot;&gt;Serializable&lt;/span&gt;]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;color: blue; font-size: x-small;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt;  &lt;span style=&quot;color: #2b91af;&quot;&gt;ParentSampleDomainObject&lt;/span&gt; : &lt;span style=&quot;color: #2b91af;&quot;&gt;BaseEntity&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; ParentSampleDomainObject()&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;        Children  = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af;&quot;&gt;List&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #2b91af;&quot;&gt;SampleDomainObject&lt;/span&gt;&amp;gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: #2b91af;&quot;&gt;IList&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #2b91af;&quot;&gt;SampleDomainObject&lt;/span&gt;&amp;gt;  Children { &lt;span style=&quot;color: blue;&quot;&gt;get&lt;/span&gt;; &lt;span style=&quot;color: blue;&quot;&gt;set&lt;/span&gt;;  }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;virtual&lt;/span&gt;  &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; AddChild(&lt;span style=&quot;color: #2b91af;&quot;&gt;SampleDomainObject&lt;/span&gt;  child)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;        Children.Add(child);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;        child.Parent = &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; RemoveChild(&lt;span style=&quot;color: #2b91af;&quot;&gt;SampleDomainObject&lt;/span&gt;  child)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;        Children.Remove(child);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    }    &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;[&lt;span style=&quot;color: #2b91af;&quot;&gt;Serializable&lt;/span&gt;]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;color: blue; font-size: x-small;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt;  &lt;span style=&quot;color: #2b91af;&quot;&gt;SampleDomainObject&lt;/span&gt; : &lt;span style=&quot;color: #2b91af;&quot;&gt;BaseEntity&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt;&amp;gt; , &lt;b&gt;&lt;span style=&quot;color: #2b91af;&quot;&gt;ISoftDeletable&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #2b91af; font-size: x-small;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; Name { &lt;span style=&quot;color: blue;&quot;&gt;get&lt;/span&gt;; &lt;span style=&quot;color: blue;&quot;&gt;set&lt;/span&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;bool&lt;/span&gt; IsDeleted { &lt;span style=&quot;color: blue;&quot;&gt;get&lt;/span&gt;;   &lt;span style=&quot;color: blue;&quot;&gt;set&lt;/span&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;virtual&lt;/span&gt;  &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; MarkAsDeleted()&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;         IsDeleted = &lt;span style=&quot;color: blue;&quot;&gt;true&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: #2b91af;&quot;&gt;ParentSampleDomainObject&lt;/span&gt; Parent { &lt;span style=&quot;color: blue;&quot;&gt;get&lt;/span&gt;; &lt;span style=&quot;color: blue;&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;internal&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;set&lt;/span&gt;; }&lt;br /&gt;
}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;color: blue; font-size: x-small;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;style&gt;
 &lt;!--  /* Font Definitions */  @font-face  {font-family:&quot;Cambria Math&quot;;  panose-1:2 4 5 3 5 4 6 3 2 4;  mso-font-alt:&quot;Calisto MT&quot;;  mso-font-charset:0;  mso-generic-font-family:roman;  mso-font-pitch:variable;  mso-font-signature:-1610611985 1107304683 0 0 159 0;} @font-face  {font-family:Calibri;  panose-1:2 15 5 2 2 2 4 3 2 4;  mso-font-alt:&quot;Century Gothic&quot;;  mso-font-charset:0;  mso-generic-font-family:swiss;  mso-font-pitch:variable;  mso-font-signature:-1610611985 1073750139 0 0 159 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal  {mso-style-unhide:no;  mso-style-qformat:yes;  mso-style-parent:&quot;&quot;;  margin:0cm;  margin-bottom:.0001pt;  mso-pagination:widow-orphan;  font-size:11.0pt;  font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;  mso-fareast-font-family:Calibri;  mso-fareast-theme-font:minor-latin;  mso-bidi-font-family:&quot;Times New Roman&quot;;} .MsoChpDefault  {mso-style-type:export-only;  mso-default-props:yes;  font-size:10.0pt;  mso-ansi-font-size:10.0pt;  mso-bidi-font-size:10.0pt;} @page Section1  {size:612.0pt 792.0pt;  margin:72.0pt 72.0pt 72.0pt 72.0pt;  mso-header-margin:36.0pt;  mso-footer-margin:36.0pt;  mso-paper-source:0;} div.Section1  {page:Section1;} --&gt; 
&lt;/style&gt;  &lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;color: blue; font-size: x-small;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af;&quot;&gt;SoftDeleteListener&lt;/span&gt;  : &lt;span style=&quot;color: #2b91af;&quot;&gt;DefaultDeleteEventListener&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;        &lt;span style=&quot;color: blue;&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; DeleteEntity(&lt;span style=&quot;color: #2b91af;&quot;&gt;IEventSource&lt;/span&gt;  session, &lt;span style=&quot;color: blue;&quot;&gt;object&lt;/span&gt; entity,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;            &lt;span style=&quot;color: #2b91af;&quot;&gt;EntityEntry&lt;/span&gt;  entityEntry, &lt;span style=&quot;color: blue;&quot;&gt;bool&lt;/span&gt; isCascadeDeleteEnabled,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;            &lt;span style=&quot;color: #2b91af;&quot;&gt;IEntityPersister&lt;/span&gt;  persister, &lt;span style=&quot;color: #2b91af;&quot;&gt;ISet&lt;/span&gt; transientEntities)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;        {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;            &lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt; (entity &lt;span style=&quot;color: blue;&quot;&gt;is&lt;/span&gt; &lt;span style=&quot;color: #2b91af;&quot;&gt;ISoftDeletable&lt;/span&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;            {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                 &lt;b&gt;&lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt;&lt;/b&gt;&lt;b&gt; e = (&lt;span style=&quot;color: #2b91af;&quot;&gt;ISoftDeletable&lt;/span&gt;)entity;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;b&gt;            e.MarkAsDeleted();&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                &lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt;(entity &lt;span style=&quot;color: blue;&quot;&gt;is&lt;/span&gt; &lt;span style=&quot;color: #2b91af;&quot;&gt;IAuditableRecord&lt;/span&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                     &lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; a = (&lt;span style=&quot;color: #2b91af;&quot;&gt;IAuditableRecord&lt;/span&gt;)  entity;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                     &lt;span style=&quot;color: #2b91af;&quot;&gt;AuditListener&lt;/span&gt;.SetAuditInfo(a);&lt;span style=&quot;color: green;&quot;&gt;//need to have a log of when this was actually deleted,  probably the intent of the soft delete!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                CascadeBeforeDelete(session, persister,  entity, entityEntry, transientEntities);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                CascadeAfterDelete(session, persister,  entity, transientEntities);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;            }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;            &lt;span style=&quot;color: blue;&quot;&gt;else&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;            {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                 &lt;span style=&quot;color: blue;&quot;&gt;base&lt;/span&gt;.DeleteEntity(session, entity,  entityEntry, isCascadeDeleteEnabled,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;                    persister, transientEntities);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;            }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;        }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;</description><link>http://rhysc.blogspot.com/2010/04/soft-deletes-in-nhibernate.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-7129100990439464141</guid><pubDate>Tue, 27 Apr 2010 14:19:00 +0000</pubDate><atom:updated>2010-04-29T19:01:15.927-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Best Practices</category><category domain="http://www.blogger.com/atom/ns#">Build</category><category domain="http://www.blogger.com/atom/ns#">Continuous Integration</category><category domain="http://www.blogger.com/atom/ns#">Deployment</category><title>Begining with the end in mind</title><description>A long time ago, what feels like a previous life, I used to train  bodybuilders. Yeah, weird, I know. I actually learnt a lot from this  subculture: discipline, sacrifice and hard work are things you can not  escape in that life. One huge lesson I picked up that many missed was  &quot;&lt;a href=&quot;https://www.stephencovey.com/7habits/7habits-habit2.php&quot;&gt;Begin with the end in mind&lt;/a&gt;&quot;. The art of bodybuilding is often confused  with weight lifting. The number of competitors that complained that a  physically weaker contestant beat them amazed me. Being able to bench  more than your opposition counts for nothing.&lt;br /&gt;
In the sport of bodybuilding the winner is decided by a panel of judges; that&#39;s right, you are judged by humans.  It is the image you present that they must judge you on. You may even  have a better physique but if you do not display it better than the  others you can lose. For this reason all of my athletes posed at every  training session. In the middle of the gym, in front of mirrors down to  their underwear, unashamedly posing as if they were in front of a panel of judges. We would critique, take photos, film it, change the lighting... I never saw any other body builders do this. I am sure that why, collectively, they won several, national and international  championships.&lt;br /&gt;
&lt;br /&gt;
Now ask yourself: Are you training for game day?&lt;br /&gt;
For us this is deploying  to the production environment.&lt;br /&gt;
Are you practicing it everyday?&lt;br /&gt;
You  should be.&lt;br /&gt;
&lt;br /&gt;
If you are doing manual deployments you are a weight lifter in a  bodybuilding show. You will lose.&lt;br /&gt;
To be honest we have it better than body builders. We have no competitors and we have predefined requirements. We can measure our performance, they cant, they can only contrast and compare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So what do we need to do to prepare for the big day? Well first and foremost don&#39;t make it a big day. Make it just like every other day. Make deployments part of your daily routine and start deploying from day one. Personally I like to have automated deployments working prior to writing any business code. Infrastructure cruft should be done in iteration zero and deployments are infrastructure cruft.&lt;br /&gt;
&lt;br /&gt;
A daily routine makes deployments so easy the are a non event. This usually mean defining everything you need to do to do a deployment then scripting it - Writing the best code in the world means nothing if the deployment is  botched... and manual deployments get botched.&lt;br /&gt;
&lt;br /&gt;
Deployments should also cover all the steps you will do on production  deployment day, they do not cover just what needs to get done to make the application work on a developers box.&lt;br /&gt;
&lt;br /&gt;
Define where you production environment is at and then work from there. If your testing environments are not the same, you should question: why? The more similar they are the less likely you are of having deployment issues. Where I currently work we have 5 environments&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Developers machine&lt;/li&gt;
&lt;li&gt;&quot;Development&quot; Environment - automated CI deployment&lt;/li&gt;
&lt;li&gt;Test&lt;/li&gt;
&lt;li&gt; UAT&lt;/li&gt;
&lt;li&gt;Production&lt;/li&gt;
&lt;/ol&gt;The developer machine I consider an environment. I often get latest and (sometimes) hit F5 and run the application and I expect the application to work! This means I require a database that is in a valid state, external services to work, file paths to be correctly set up etc. For this reason I like developers to have local sandbox which includes local databases. Nothing pisses me off more than when I am running an app and some bugger has cleared the dev database for testing a script breaking my flow. Having your own database also forces you to properly script database changes in a sane manner. Checking in those changes and getting latest, running you build script should get you up and running every time. See &lt;a href=&quot;http://www.lostechies.com/blogs/hex/archive/2009/09/17/continuous-database-integration-video.aspx&quot;&gt;Tarantino&lt;/a&gt; from &lt;a href=&quot;http://code.google.com/p/tarantino/wiki/DatabaseChangeManagement&quot;&gt;Eric Hexter&lt;/a&gt; or&amp;nbsp; &lt;a href=&quot;http://github.com/chucknorris/roundhouse&quot;&gt;RoundHouse&lt;/a&gt; from the &lt;a href=&quot;http://github.com/chucknorris&quot;&gt;ChuckNorris&lt;/a&gt; framework for a simple way to get database migrations working cleanly in a .Net-SQL world.&lt;br /&gt;
&lt;br /&gt;
The Development Environment is a name sake. No development is done on it, but it is owned by the developers. We may use this for debugging on a production-like environment if things go pear shaped, I just never have. Its main purpose is for, IMO, automated deployments from our build server. If anything breaks here the red light on the build server goes on and the check in for that build fails. The steps to do this include&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Cleaning the server - ie getting rid of the last deployment and backing it up &lt;/li&gt;
&lt;li&gt;Setting up the server including&lt;/li&gt;

&lt;ul&gt;&lt;li&gt; creating apps pools/virtual and physical directories,&amp;nbsp;&lt;/li&gt;
&lt;li&gt;ensuring dependencies are present eg MSMQ, DTC etc&lt;/li&gt;
&lt;li&gt; ensuring the dependencies can run, ie queues are set up, services are running&lt;/li&gt;
&lt;li&gt;setting up account privileges&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Deploying the packages to the server and installing it if applicable&lt;/li&gt;
&lt;li&gt;Running SQL scripts including&lt;/li&gt;

&lt;ul&gt;&lt;li&gt;creating users roles and permissions&lt;/li&gt;
&lt;li&gt;creating the database objects (tables, views, keys constraints, triggers etc)&lt;/li&gt;
&lt;li&gt;creating required reference data&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Testing the deployment &lt;/li&gt;

&lt;ul&gt;&lt;li&gt;creating test data&lt;/li&gt;
&lt;li&gt;running high level acceptance and smoke tests&lt;/li&gt;
&lt;/ul&gt;&lt;/ol&gt;If you can get to this stage then is it not obvious that doing a test deployment is going to be next to trivial? Migrating to the test environment should be the same as migrating UAT and therefore the same as Production. Production deployments should therefore be just a matter of going through the motions.&lt;br /&gt;
&lt;br /&gt;
This also means that you may need various scripts or at least functions with in these scripts to carry out these various steps. Obviously if the Production environment is already set up we do not need to do it again, and the deployment scripts should reflect that. Just like in normal code use pre-conditions and post-conditions to enforce a correct deployment. If certain set ups are not required log it and move on, just make sure it is part of the agreed process.&lt;br /&gt;
&lt;br /&gt;
DBAs are involved and decide how you want to manage your deployments. Keep reminding the team that this should be streamlined.&lt;br /&gt;
One thing that often trip up teams is permission issues. Personally I prefer not having access to anything outside of the development environments (I&#39;m pretty sure I am alone on this one). As far as I am concerned the testers can deploy there own stuff. It will be the same script that the SysAdmins and DBAs will run in UAT and production, why should I do it? I have code to write! They can have permission to run the scripts in their own environment making sure that no manual step has been introduced by any developer along the way. This separation I feel further reduces risk of failed deployments. If the deployment to Test does fail then they can raise a bug, roll back and tell the developers what they think of them. Sure this will be embarrassing and it does happen, but would you rather it done in the confines of the IT department or in full view of the customers?&lt;br /&gt;
&lt;br /&gt;
This brings us back to what we are here for : to fix a customers problem. I assume this typically means delivering working software. Working software on your development machine has not fixed the customers problem, that&#39;s like being a weight lifter in a body building show. Don&#39;t be that guy, think about the end game and make sure that each day you are working towards that end goal of providing you customer with a business solution, in the cleanest possible way. &lt;br /&gt;
&lt;br /&gt;
*Sorry for putting the images of most nude men in your mind, it (probably) wont happen again</description><link>http://rhysc.blogspot.com/2010/04/begining-with-end-in-mind.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-4679839678917454560</guid><pubDate>Mon, 26 Apr 2010 14:28:00 +0000</pubDate><atom:updated>2010-04-26T07:28:26.145-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">communication</category><category domain="http://www.blogger.com/atom/ns#">UML</category><title>Continuous Improvement - Bringing back UML</title><description>Continuous improvement is something we should all endeavour to pursue on a daily basis irrelevant of our chosen field. For me I am not a natural geek. I never built my own computer and never wrote my own gaming engine. I am much more interested in business than computers. What I love about computers is the way they can stream line our processes and, ironically, how unforgiving they are. They do what they are told, not you you meant. To me this poses a nice daily challenge and keeps my brain from turning to mush at work. Because i am not a natural geek I have to actively push myself to learn things with regard to IT.&lt;br /&gt;
&lt;br /&gt;
When PowerShell came out a few years ago I looked at it in fear. I have never really been a shell guy. My &#39;nix mates were always playing on the green screens and I secretly knew there was a lot of power there but it was too much of a mind shift from the comfort of my drag-n-drop/intellisense laced world... But I knew it was a weakness and jumped in feet first.&lt;br /&gt;
&lt;br /&gt;
Although i am still a complete n00b at PowerShell I can get what i need done with it. I am comfortable with the tools and have got real return on my learning investment. I got uncomfortable and it paid off in spades. I have even moved on to PSake and replaced most of my build and deployments steps to be completely PowerShell/PSake based, a feat I am pretty proud of. It has also helped immensely in me picking up Rails and Git, both of which are command line driven.&lt;br /&gt;
&lt;br /&gt;
For me the next thing I think I really have to tackle is UML. I have dodged it for years.&lt;br /&gt;
I draw diagrams a lot. I use a white board every day and like to draw while I talk. I feel in mixed audiences it help get points across by using multiple forms of communication at the same time, voice body language and diagrams. However I am communicating I should be adhering to common practices where possible (as my last post pushed), when there is a common language, you should use it.&lt;br /&gt;
For diagrams in nerd world its all about UML.&lt;br /&gt;
&lt;br /&gt;
My dislike for UML stems from my dislike of concrete documentation. I have inherited too many projects that have had documentation that did not marry up to the implementation, with UML typically being one of the worst offenders. It is incredibly frustrating and most importantly wasteful; wasted time, money and trees (paper has to come from somewhere)!&lt;br /&gt;
&lt;br /&gt;
So I sit thinking that perhaps I was throwing the baby out with the bath water; UML is not bad, inaccurate documentation is bad. If I am to communicate with diagrams then I should use the common language. I also understand there is a time to be pragmatic and a time to be dogmatic. Most of the time a couple of boxes with some lines joining them will suffice but the ability to step up to the more accurate implementation is a worthwhile ability.&lt;br /&gt;
So my UML journey begins... or at least is reborn.</description><link>http://rhysc.blogspot.com/2010/04/continuous-improvement-bringing-back.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-7725367947844150921</guid><pubDate>Mon, 26 Apr 2010 03:32:00 +0000</pubDate><atom:updated>2010-04-26T03:56:13.234-07:00</atom:updated><title>Common language and Patterns</title><description>Imagine if craftsman from other industries called everything basic patterns they used they did by different names. Instead of a butterfly stitch a doctor called it &quot;the sticky skin healer&quot; or a carpenter calling a dovetail join &quot;the zig zag corner&quot;... it just wouldn&#39;t fly.&lt;br /&gt;Well unfortunately this is not common in our industry, it is the norm.&lt;br /&gt;Firstly I want to define what &quot;our industry&quot; is:&lt;br /&gt;It is not computer science.&lt;br /&gt;It is, if anything, Information Systems.&lt;br /&gt;We push data around, make it easy for users to persist and transmit data so systems or other users can make decisions, business decisions. All of this is intended to some how improve the bottom line of the client and/or the company you are working for. People forget this. Our job is 99.999% of the time about making money. The Wiki on cucumbers git hub site has a good blurb about defining features and asking &quot;why?&quot; with regard to implementing features, you should get to the following reasons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Protect revenue&lt;/li&gt;&lt;li&gt;    Increase revenue&lt;/li&gt;&lt;li&gt;    Manage cost&lt;/li&gt;&lt;li&gt;    Increase brand value&lt;/li&gt;&lt;li&gt;    Make the product remarkable&lt;/li&gt;&lt;li&gt;    Provide more value to your customers&lt;/li&gt;&lt;/ul&gt;Now this is clearly for a product; I have no problem with team defining what the underlying drivers for &lt;span style=&quot;font-style: italic;&quot;&gt;their&lt;/span&gt; project, department  or business are but being able to see how a feature helps enhance that is important.&lt;br /&gt;&lt;br /&gt;Anyway... back to language.&lt;br /&gt;Language and the words we use are very underrated. I think it is possible that, in our industry, communication skills are so rare (hey, we are nerds!) that we trivialise the importance of the words we use. Evans makes it very clear that the ubiquitous language is a key aspect of DDD and the same can be said about whole industries and the language used by the individuals that make up that industry.&lt;br /&gt;This is why patterns books are popular. If I want to have a discussion with a developer at another firm to bounce questions off them, which I frequently do, if we do not share the same language then we spend half the time getting our terms aligned. There is a way to avoid this: understand the common language!&lt;br /&gt;How? Well, I&#39;m sorry but you are going to have to pick up a book or two... OK that&#39;s a lie. You are going to have to read a crap load. Hey, we get paid well, I &lt;span style=&quot;font-style: italic;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;expect&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-style: italic; font-weight: bold;&quot;&gt;&lt;/span&gt; senior developers and consultants (again, in our industry) to have read the books I am about to describe.&lt;br /&gt;&lt;br /&gt;This list is an ordered list of pattern books, it focuses on patterns i.e. a language based term to describe a common approach to solving a problem. The language is as important as the fix&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Refactoring - Fowler&lt;/li&gt;&lt;li&gt;PEAA - Fowler&lt;/li&gt;&lt;li&gt;Head First Design Patterns -or- Refactoring To Patterns&lt;/li&gt;&lt;li&gt;APPP - Uncle Bob&lt;/li&gt;&lt;li&gt;Refactoring Databases - Ambler&lt;/li&gt;&lt;li&gt;GoF&lt;/li&gt;&lt;li&gt;XUnit Test Patterns - Meszaros&lt;/li&gt;&lt;li&gt;EIP - Hohpe&lt;/li&gt;&lt;li&gt;DDD - Evans&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;There is also one I really cant wait for and that is the forthcoming &lt;a href=&quot;http://www.jeremydmiller.com/ppatterns/default.aspx&quot;&gt;Presentation Patterns&lt;/a&gt; by &lt;a href=&quot;http://codebetter.com/blogs/jeremy.miller/&quot;&gt;JDM&lt;/a&gt;; which should round out the whole stack.&lt;br /&gt;To be honest this reading list would take the average developer that has a family and a life about a year to read. I&#39;m sorry. Suck it up.&lt;br /&gt;&lt;br /&gt;The order I have presented this list in is very deliberate. People will argue that GoF should be first. I heartily disagree. Gof is a &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;hard&lt;/span&gt; book to read, with out having the understanding of refactoring and the softening blow of &quot;Head First&quot; the book is too much for the average nerd. I know this because it was my first patterns book. I have read it 4 times and only the last 2 time I have actually got anything out of it.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/&quot;&gt;Refactoring &lt;/a&gt;&lt;br /&gt;I feel this book is a minimum in a developers arsenal of pattern books. With this you at least can understand why resharper is doing what it is doing. It defines some basic terms that are low level enough that it is applicable to most developers irrelevant of the layers they work in. Some common terms like parameter object are introduced to the developers language&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420/&quot;&gt;PEAA&lt;/a&gt;&lt;br /&gt;Although he book references a metric tonne of other books, I think its aggregation of basics is its strength. The 2 book approach is great and the patterns introduced are very basic and high level enough that the are able to be picked up quickly. Read in conjunction with conversations with an experience developer that uses these patterns regularly and the developer should be very familiar with these patterns very quickly. This is a great book for Book Club type discussions too (hint hint @wolfbyte)&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124/&quot;&gt;Head First Design Patterns&lt;/a&gt; -or- &lt;a href=&quot;http://www.amazon.com/Refactoring-Patterns-Joshua-Kerievsky/dp/0321213351/&quot;&gt;Refactoring To Patterns&lt;/a&gt;&lt;br /&gt;These two books are a softer introduction to lower level patterns when compared to the godfather of patterns books, GoF. These are much easier to read and depending on the developer one may prefer one over the other. Ideally read both but read at least one of these prior to continuing down the stack. You may find it odd that the list starts with a low level pattern book (Refactoring) then a high level book (PEAA) then something in between. The pattern described in HFDP and RTP are more abstract patterns that require much more thought than the high level patterns in PEAA eg specific patterns like Table Gateway or ActiveRecord. I also find it easier to show what tool implements the PEAA pattern, eg Rails ActiveRecord or Castle Activerecord, NHibernate as DataMapper (all as examples of Lazy loading) etc&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258/&quot;&gt;&lt;span style=&quot;text-decoration: underline;&quot;&gt;APPP&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;This book is great at helping developers step up to actually writing clean, readable, maintainable code by showing the patterns that you can use on a daily basis. &lt;strike&gt;S.O.L.D.I&lt;/strike&gt; S.O.L.I.D is introduced to the reader. Unfortunately SOLID has just become another rote learnt acronym/pattern that is infrequently applied. I have found this does however allow code reviews to now have a common language and not just &quot;um this code looks ugly&quot; type code reviews, which i have been guilty of in the past.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.amazon.com/Refactoring-Databases-Evolutionary-Database-Design/dp/0321293533/&quot;&gt;Refactoring Databases&lt;/a&gt;&lt;br /&gt;This book is in here by necessity. I doubt many .Net developers would get much from this. We have been force feed SQL drizzled in a Table sauce and Views jus and a side of Stored Procs for years. We know Databases, at times, it feels too well. However if you are from a non data base driven framework then this is a necessary read. I&#39;m talking to you Ruby and Java kids. You lucky bastard get ORMs by default. In the twilight of the SQL age this book may seem a bit legacy but if you are truly and enterprise developer you will be dealing with SQL for years to come. I&#39;m sorry, I really am ;)&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/&quot;&gt;GoF&lt;/a&gt;&lt;br /&gt;Ahhh. The serotonin of pattern books. If you have insomnia this is for you. Its a great yet boring read, hmm what a paradox. This is just developer tax, its rite of passage, a necessity. Please note that just because a pattern exists it does not mean it must always be used, that it should ever be used or that it is not hard wired into you language. I&#39;ll let the reader guess/figure what I&#39;m referring to.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you have got through all of these books in my mind you have done you due diligence and are now allowed near an IDE.. OK I&#39;m just kidding, but seriously I believe all of those previous books are minimum requirements for some one who leads a team of other software developers or consults. Below are the one you should continue on to if you want to be an above average developer&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.amazon.com/xUnit-Test-Patterns-Refactoring-Code/dp/0131495054/&quot;&gt;XUnit Test Patterns&lt;/a&gt;&lt;br /&gt;By this stage you should be testing you software. The XUnit book, although not my favourite Testing book (that goes to The Art of Unit Testing) it is the best in describing the patterns of unit testing. Understanding these patterns will help you help other learn how to correctly add TDD to their skill set and firm up the teams language around key terms like doubles, fakes, stubs, mocks and spies; all things that are commonly misunderstood&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683/&quot;&gt;EIP &lt;/a&gt;&lt;br /&gt;This book cover various messaging patterns that relate to integrating system. Ideally you should read this book prior to using any ESB type framework like NServiceBus or MassTransit. If you have read this book and are using these patterns without having read or understood the previous books I fear you may have a big distributed mess on your hands. This is a great book but IMO this system you would tend to build using these patterns are most like system that should have been built on the patterns from the other books. If you do any integration you owe it to your self to read this, which means unless you are just doing the integration, reading all the other books first ;)&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683/&quot;&gt;DDD&lt;/a&gt;&lt;br /&gt;My favourite and I believe the most misunderstood book of the lot. This book is not just a code book it a process book. It raises the issue of language and introduces the notion of a ubiquitous language that the team including the stakeholders/SME/Users understand.&lt;br /&gt;I believe this book has pushed what I can produce for a customer to the next level. The code feel more aligned with the business as opposed to just getting a task done. The closer code matches business processes and concepts the easier it can change with the business too.&lt;br /&gt;&lt;br /&gt;So there it is. My list of pattern books I assume a Tech lead or Consultant has read, understands and implements. These are not the be all and end all of pattern books but I believe they cover the bases. Please note there are a suite of other books that are not pattern books that I believe are also &quot;essential reads&quot;, but that is perhaps another blog post.&lt;br /&gt;&lt;br /&gt;Would love to hear feedback,&lt;br /&gt;cheers Rhys</description><link>http://rhysc.blogspot.com/2010/04/common-language-and-patterns.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-8712801377442807010</guid><pubDate>Wed, 21 Apr 2010 07:56:00 +0000</pubDate><atom:updated>2010-04-21T18:12:46.970-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Document Databases</category><title>NoSQL &amp;amp; Document databases</title><description>I am really loving the NOSQL movement at the moment, however there seems to be a lot of confusion as to when it is appropriate to use them.&lt;br /&gt;&lt;br /&gt;Significant things to considered are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Atomic transactions are only for single operations. You can&#39;t really have long running or nested transactions (ACID rule a different).&lt;/li&gt;&lt;li&gt;Joins don&#39;t make sense so don&#39;t expect to use them when designing the system&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Document databases are typically schema-less. This means adding new properties is much less of a hassle than in SQL-land, especially once you are in production.&lt;/li&gt;&lt;li&gt;The notion of an aggregate root fits perfectly with a document so the idea of using a DocDB for DDD is appealing (assuming transactions are not required)&lt;/li&gt;&lt;li&gt;DocDBs tend to scale horizontally very well unlike our SQL counterparts which tend to only scale vertically without huge headaches&lt;/li&gt;&lt;li&gt;Read and write performance is possibly the opposite of what is expected with very fast writes (I understand) being the norm.&lt;/li&gt;&lt;li&gt;Queries are done differently. MongoDB for example uses JavaScript as it query language (this does not mean it is used in the web tier!)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Several uses for document databases come to mind:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;High volume, low value writes; eg user data entry on social sites; this is not business critical but potentially requires easy scaling options; ie no one is going to die if you last Facebook update doesn&#39;t go through to all the DB servers instantaneously.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Auditing; One area I&#39;m keen on is command persistence. I like the idea of having a trail of all command sent to a component, it becomes a self documenting timeline of what users were trying to do to the system. When a command is handled by a component it can just write the whole serialized object to a DocDB, thereby capturing all the info without being bound to a schema (audit is version agnostic). The command can then be processed by the component. I will admit that an Object DB is also suitable for this.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Things not to use Document Database for is high value transaction heavy stuff i.e. banking transactions or thing that inherently require SQL... whatever use case that may be.&lt;br /&gt;&lt;br /&gt;Hope this helps :)</description><link>http://rhysc.blogspot.com/2010/04/nosql-document-databases.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-3656606928704746430</guid><pubDate>Fri, 16 Apr 2010 01:53:00 +0000</pubDate><atom:updated>2010-04-26T08:08:18.535-07:00</atom:updated><title>Help Me Help You</title><description>We have been lucky here in Perth that we have a very active community, well run by people who have stepped up to the plate to provide us these events. However these events are not free. We need venues, we often get prizes and some sweet swag. I don&#39;t think some of our attendees quite understand that without that support we have no event.&lt;br /&gt;
We are also fortunate enough to have sponsors we actully like! For this reason when we make a plug it not just because they are a sponsor but because we either use the product or service (or want to) ourselves. As our audiene is largely made of business developers I thought they would understand these basic back scratching processes.&lt;br /&gt;
Anyway, below is a list companies or products that have made many live better by helping out a technical community I&#39;m involved in AND I recommend professionally:&lt;br /&gt;
&lt;a href=&quot;http://www.jetbrains.com/&quot;&gt;JetBrains&lt;/a&gt;-ReSharper, Teamcity&lt;br /&gt;
&lt;a href=&quot;http://tekpub.com/&quot;&gt;TekPub&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://readify.net/&quot;&gt;Readify&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.beacon.com.au/&quot;&gt;Beacon&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://excom.com.au/&quot;&gt;Excom&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.red-gate.com/&quot;&gt;Redgate&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Thanks. I like your stuff, recommend you and thank you for helping us out. Also want to thank Mitch Wheat and Mike @wolfbyte for organizing  us presentations every month; you are appreciated!</description><link>http://rhysc.blogspot.com/2010/04/help-me-help-you.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-1582546675956055646</guid><pubDate>Tue, 13 Apr 2010 01:28:00 +0000</pubDate><atom:updated>2010-04-12T19:28:07.701-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">DDD</category><category domain="http://www.blogger.com/atom/ns#">Testing</category><title>Testing with Domian Driven Design</title><description>&lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_0&quot;&gt;DDD&lt;/span&gt; is a hairy beast. It feels like everyone has a slightly different opinion of what it is. I personally thought I had a pretty good grasp on it until I caught up with &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_1&quot;&gt;Udi&lt;/span&gt; &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_2&quot;&gt;Dahan&lt;/span&gt; earlier this year where he (as per usual) completely turn my understanding on its head.&lt;br /&gt;That being said I believe the way I am approaching the current project is in line with what I believe the majority of people believe &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_3&quot;&gt;DDD&lt;/span&gt; is, correctly or otherwise.&lt;br /&gt;Key aspects in this project that help make it resemble a &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_4&quot;&gt;DDD&lt;/span&gt; domain are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The level of understanding the &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_5&quot;&gt;devs&lt;/span&gt; have and the ubiquitous language that is in use and they way it is constantly evolving &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_6&quot;&gt;amoungts&lt;/span&gt; all team &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_7&quot;&gt;memebers&lt;/span&gt;, including our &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_8&quot;&gt;SMEs&lt;/span&gt;/Users&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The general structure of the code - repositories, services, aggregate roots comprised of entities and value types etc etc&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;To be honest one could argue, that like most &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_9&quot;&gt;DDD&lt;/span&gt; projects, it is just clean &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_10&quot;&gt;OO&lt;/span&gt; coding. It is; that doesn&#39;t mean that there isn&#39;t something that others could glean of of the project, such as what we are doing to keep things clean and help with creating nice tests.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;First and foremost follow TDD and &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_11&quot;&gt;BDD&lt;/span&gt; if possible&lt;/span&gt;&lt;br /&gt;If you have a good understanding of the component you are building then writing explicit specifications should be easy. Do this with your BA and &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_12&quot;&gt;SME&lt;/span&gt; make sure the tests are not shallow low value tests. Investigate what &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_13&quot;&gt;BDD&lt;/span&gt; is and see if one of the many framework fit your teams needs. Personally I am still using &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_14&quot;&gt;xUnit&lt;/span&gt; frameworks and am creating elaborate contexts on which I make assertions. My fixture set ups can sometimes be complex but my test methods are very clear &amp;amp; clean and can often just be one line assert statements.  I have not found a &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_15&quot;&gt;BDD&lt;/span&gt; framework that sits well with me in the .Net world like Cucumber does in my Rails development, so I will continue down this path till I find something I like better than explicit and somewhat elaborate &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_16&quot;&gt;xUnit&lt;/span&gt; styled tests.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;The domain should remain as pure as humanly possibly&lt;/span&gt;&lt;br /&gt;Anything that is public should have a good reason for being so. Unfortunately most developers use public as their default. This is bad practice as it produces a very non intuitive &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_17&quot;&gt;API&lt;/span&gt;. Use access to help show the other developers how you intended the &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_18&quot;&gt;API&lt;/span&gt; to be used.&lt;br /&gt;Typically, IMO, this means protected virtual by default. (I&#39;m an NH &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_19&quot;&gt;fanboi&lt;/span&gt;). Also &lt;span class=&quot;blsp-spelling-corrected&quot; id=&quot;SPELLING_ERROR_20&quot;&gt;restrict&lt;/span&gt; what you return. I personally &lt;span class=&quot;blsp-spelling-corrected&quot; id=&quot;SPELLING_ERROR_21&quot;&gt;don&#39;t&lt;/span&gt; like the idea of returning child &lt;span class=&quot;blsp-spelling-corrected&quot; id=&quot;SPELLING_ERROR_22&quot;&gt;entities&lt;/span&gt; from parent entities especially &lt;span class=&quot;blsp-spelling-corrected&quot; id=&quot;SPELLING_ERROR_23&quot;&gt;aggregate&lt;/span&gt; roots. What is the consumer going to do with these entities? Most of the time a value type or projection is more appropriate and helps keep the line of ownership clean.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Modifying the domain to be more testable should be frowned upon, especially if it confused the &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_24&quot;&gt;API&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;This ties into the first point. NB : There are concession that I make that I can live with (I will cover them soon) but I believe these do not negatively affect my domain and make life easier and my intentions more explicit to the next developer&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Use subclass fakes to increase accessibility for testing&lt;/span&gt;&lt;br /&gt;I often see people making fields, properties or methods public so tests can call them. Please don&#39;t do this. If these are private definitely do not expose them. This is an indication that you are not doing TDD. Private methods generally only come from refactoring once your test pass so testing private methods is a sure sign you are not doing TDD. Internals sometimes may warrant being tested. This is OK as we can make internals visible to the test project. I generally don&#39;t mind doing this as I put this in the &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_25&quot;&gt;AssemblyInfo&lt;/span&gt; file which is recreated in my deployment anyway so there is no dodgy test orientated code in my final deployed assembly. I must say that I don&#39;t really do this a lot and i think people use this as a crutch. True TDD generally will not warrant a lot of this, However i find myself doing it a bit in my domain, possibly out of fear more than any really rational reason.&lt;br /&gt;If you really need to make something accessible to test and don&#39;t want to expose it fully then create a fake that inherits from the class and override the &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_26&quot;&gt;accessor&lt;/span&gt; in that class. Sometimes I do this to check things like IDs. Again question whether this is really needed, have faith in the TDD process!&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Allow hooks in the domain for creating child objects&lt;/span&gt;&lt;br /&gt;One thing I have used in the current project is protected factory method to create child entities. By opening up these one liners I can override the method in a fake sub class to create a fake subclass of the child: &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_27&quot;&gt;eg&lt;/span&gt; &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_28&quot;&gt;OrderFake&lt;/span&gt; will create and return an &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_29&quot;&gt;OrderLineFake&lt;/span&gt; in its &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_30&quot;&gt;CreateOrderLine&lt;/span&gt; method as opposed to the Order creating and returning an &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_31&quot;&gt;OrderLine&lt;/span&gt; in its &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_32&quot;&gt;CreateOrderLine&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;When using fakes of real domain objects make sure you are not hiding any of the real object functionality. The fakes should be as plain as possible. Adding additional logic will surely corrupt your tests. One thing to watch for is to make sure your fakes implement the same &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_33&quot;&gt;ctors&lt;/span&gt; as their parent and call into those &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_34&quot;&gt;ctors&lt;/span&gt;. Failure to do this will create a big PITA :)&lt;br /&gt;&lt;br /&gt;Next post I will talk about some issues and traps that we as a team have managed to fall into. Most of them have been things when consciously question know we shouldn&#39;t do but have managed to creep into the solution, hopefully we can help you avoid repeating our mistakes!</description><link>http://rhysc.blogspot.com/2010/04/testing-with-domian-driven-design.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-2508686047782719915</guid><pubDate>Mon, 12 Apr 2010 14:10:00 +0000</pubDate><atom:updated>2010-04-12T18:19:35.388-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">communication</category><category domain="http://www.blogger.com/atom/ns#">Testing</category><title>What is Regression Testing?</title><description>We are on a journey. The company I work for is a very large one and has suffered some lag in migrating to modern ways of software development, a situation many companies of this size often find themselves in. Fortunately the team I work with have come together to make a conscious and consistent effort to improve our area of influence. First and foremost was the introduction of a structured developer oriented testing plan. Because we are a development team we started with unit testing, integration testing and some build scripts to  run these tests. From there we have improved they way we do those tests, streamlined our scripts and made CI a solid part of our process. Automated deployments have become easier too leading to automated staged deployments. We are now at the stage where we are adding in Fitness and &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_0&quot;&gt;UI&lt;/span&gt; testing to the equation.&lt;br /&gt;&lt;br /&gt;Each of these step have been driven from the ground up. We have had to, carefully, maneuver these processes into our daily process and show the benefits to management. It has taken time but they have responded very well; so well that they are jumping on board! This is a great thing and has made all the hard work, and it was &lt;span style=&quot;font-weight: bold;&quot;&gt;hard&lt;/span&gt; work, worthwhile.&lt;br /&gt;However there are still political games to play. The language is fractured and management want to throw around terms that they don&#39;t really understand and force their idea of these terms onto the very people that introduced them to the department, sound familiar? ;)&lt;br /&gt;&lt;br /&gt;&quot;Unit Testing&quot; and &quot;Regression Testing&quot; are two of the terms &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_1&quot;&gt;du&lt;/span&gt; &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_2&quot;&gt;jour&lt;/span&gt;. Unit testing &quot;means&quot; something a developer does and regression testing is an automated &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_3&quot;&gt;UI&lt;/span&gt; test that a non techie can watch as it magically clicks away at the screen. This, as you may know, is not correct... well not strictly correct; and in a place where the language is so commonly fractured it is hard to justify fighting for seemingly such trivial victories.&lt;br /&gt;So instead I vent here.&lt;br /&gt;&lt;br /&gt;The things that i felt i needed to express most importantly are:&lt;br /&gt;&lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;Any automated test is a regression test &lt;/span&gt;&lt;br /&gt;- and -&lt;br /&gt;&lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;You do not write regression tests. &lt;/span&gt;&lt;br /&gt;What i am referring to in that last statement is merely the fact that you write a &lt;span style=&quot;font-style: italic;&quot;&gt;repeatable&lt;/span&gt; test that tests a certain unit, module or scenario, that can be &lt;span style=&quot;font-style: italic;&quot;&gt;automated&lt;/span&gt; and then your check it in to source control. The very notion that it is part of your build process/continuous integration means it now &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;acts&lt;/span&gt; as a regression test.&lt;br /&gt;So our tests that&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Test a unit, i.e. an &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_4&quot;&gt;xUnit&lt;/span&gt; framework which may also uses mocks and stubs etc&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Testing seams or integration points i.e. DB tests, file systems tests, web service tests etc&lt;br /&gt;&lt;/li&gt;&lt;li&gt;System smoke test&lt;/li&gt;&lt;li&gt;High level acceptance tests using tools like cucumber, fitness etc&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_5&quot;&gt;UI&lt;/span&gt; testing - i.e. a button clicking framework like &lt;span class=&quot;blsp-spelling-error&quot; id=&quot;SPELLING_ERROR_6&quot;&gt;QTP&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;are all regression test because the are repeatable, automated tests.&lt;br /&gt;Please don&#39;t make the mistake of thinking you will explicitly write a regression test. The test &lt;span style=&quot;font-style: italic;&quot;&gt;should test that the code produces a specific outcome&lt;/span&gt; e.g. enforces a business rule.&lt;br /&gt;The &lt;span style=&quot;font-style: italic;&quot;&gt;automation and maintenance of a healthy CI environment&lt;/span&gt; makes those tests regression tests.&lt;br /&gt;&lt;br /&gt;I guess the key here is really your CI process. If the tests can be dodged or accidentally not run somehow then this will need to be addressed.&lt;br /&gt;Make the pit of success an easy one for you team to fall in to and let them know regression tests are a side effect of good daily habits.</description><link>http://rhysc.blogspot.com/2010/04/what-is-regression-testing.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-1789604173744545711</guid><pubDate>Sun, 21 Feb 2010 15:16:00 +0000</pubDate><atom:updated>2010-02-21T07:16:37.156-08:00</atom:updated><title>InfoQ</title><description>&lt;p&gt;It still surprises me that people are not aware of the great resource that is &lt;a href=&quot;http://www.infoq.com&quot; target=&quot;_blank&quot;&gt;InfoQ&lt;/a&gt;. If you are reading this post from my web page then there is probably a big InfoQ link right in front of you. If you are like the majority then this is probably a feed and you cant see it! Anyway its a great site that I have as my home page that gives a running report of the happenings of our industry. It doesn&#39;t say anything about the latest Intel processors or have Dilbert cartoons its just enterprise development and architecture, specifically .Net/Java/Ruby, SOA and Agile; Basically stuff I am interested in on a professional level.&lt;/p&gt;  &lt;p&gt;Go check it out : &lt;a href=&quot;http://www.infoq.com&quot;&gt;http://www.infoq.com&lt;/a&gt;&lt;/p&gt;  </description><link>http://rhysc.blogspot.com/2010/02/infoq.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-6921195200450526878</guid><pubDate>Sat, 23 Jan 2010 00:44:00 +0000</pubDate><atom:updated>2010-01-22T16:44:02.770-08:00</atom:updated><title>Udi Dahan&amp;#39;s Advanced Distributed Systems Design with SOA &amp;amp; DDD</title><description>&lt;p&gt;Over the last week I have been in Melbourne attending &lt;a href=&quot;http://www.udidahan.com&quot; target=&quot;_blank&quot;&gt;Udi Dahan&#39;s&lt;/a&gt; Distributed systems course and I thought now that I am home&lt;em&gt;&amp;#160; &lt;/em&gt;will do a quick review on the course.&lt;/p&gt;  &lt;p&gt;Firstly the course is not about how to build a 3 tier system on top of a Microsoft stack. Udi is a well known M$ MVP and has a well known open source .Net project however the course is an architectural course focusing extensively on architectural concerns that are largely technology agnostic. Most of the examples at in C# and use (an abstraction of)MSMQ however I guess near on 100% of the examples could work in Java (assuming tool support). The course is also not about how to build a &lt;a href=&quot;http://thomaserl.com/&quot; target=&quot;_blank&quot;&gt;Thomas Erl&lt;/a&gt; style web of web services. &lt;/p&gt;  &lt;p&gt;To be honest leave all your preconceived ideas of architecture at home... it will just make life easier. &lt;/p&gt;  &lt;p&gt;There were jokes of requiring a support group for attendees of the course, you will feel like Neo after he took the &lt;a href=&quot;http://www.youtube.com/watch?v=arcJksDgCOU&quot; target=&quot;_blank&quot;&gt;Red Pill&lt;/a&gt;; naked alone and very... well humbled.. or stupid, depends how diplomatic you want to be. Because people inherently don&#39;t like change there was the typical amount of resistance; given there would have been several hundred years of experience in building large systems in the small room and I would consider these guys some of the best minds in the country in terms of .Net, the red pill was pretty hard to swallow. However like Neo with Morpheus, we put our faith in Udi and let him show us the way.&lt;/p&gt;  &lt;p&gt;Seriously though, the course was incredible, I think the overwhelming majority learnt more in those 5 days about designing large scale scalable enterprise architectures than they had over the 5 years of their career.&lt;/p&gt;  &lt;p&gt;Just a side note about Udi: he would have to be the most tolerant presenter and teacher I have ever had. These concept were hard to grok all in one go, Udi allowed for lots of questions lots and ensured that the audience knew enough to progress. Sure a lot of the time I was thinking... &amp;quot;what the?&amp;quot; but typically the very next slide answered my question. In terms of raw ability, I have never met anyone like him. Yes he is an outstanding architect, truly outstanding, seriously never met anyone that can walk the walk like Udi in those terms. However to be a truly great architect you have to be a bit more than the guy who is drawing the UML. He has a fantastic mind that has a great understanding of business, organisational management, psychology and his technical understanding is better than all but the absolute best coders. This man is no Ivory Tower Architect. He would be just at home in the largest corporation&amp;#160; boardroom having discussions with CTOs as he would pair programming with the guy at the boiler plate writing the code. Possibly a genius.&lt;/p&gt;  &lt;p&gt;Request Response is dead... well, its not but... well go on the course, its freaking awesome just be ready to start looking for a support group... you&#39;ll need it ;)&lt;/p&gt;  &lt;p&gt;**********************&lt;/p&gt;  &lt;p&gt;Course outline as it was for our course (from &lt;a title=&quot;http://www.udidahan.com/training/&quot; href=&quot;http://www.udidahan.com/training/&quot;&gt;http://www.udidahan.com/training/&lt;/a&gt; on 23 Jan 2010) :&lt;/p&gt;  &lt;p&gt;The Rhys Campbell Course Rating: 10/10&lt;/p&gt;  &lt;h5&gt;Advanced Distributed Systems Design using SOA &amp;amp; DDD&lt;/h5&gt;  &lt;p&gt;Duration: 5 days&lt;/p&gt;  &lt;h6&gt;Introduction&lt;/h6&gt;  &lt;p&gt;Designing large-scale distributed systems is hard. New technologies make it easier to comply with today&amp;#8217;s communications and security standards, but don&amp;#8217;t auto-magically give you a robust and scalable system. Join Udi for a course packed with the wisdom of companies like SUN, Amazon, and EBay.&lt;/p&gt;  &lt;p&gt;Tried-and-true theories and fallacies will be shown, keeping you from making those same costly mistakes today. Communications patterns like publish/subscribe and correlated one-way request/response will be used in conjunction with advanced object-oriented state management practices for long-running workflows. If you enjoy deep architectural discussion, if you are in charge of building a large-scale distributed system, if you want to know more about how the big guys run their systems, this is for you.&lt;/p&gt;  &lt;h6&gt;Audience&lt;/h6&gt;  &lt;p&gt;This workshop is targeted at team leads, application and solutions architects, as well as technologists who are involved in making decisions about the overall system design of software products and projects.&lt;/p&gt;  &lt;h6&gt;Course Topics&lt;/h6&gt;  &lt;p&gt;&lt;b&gt;Module 1: Distributed Systems Theory&lt;/b&gt;    &lt;br /&gt;Decades of distributed systems development have taught us many lessons. In this module we&amp;#8217;ll cover many historical mistakes as well as proven best practices for scalable and robust design. Topics include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;8 fallacies of distributed systems &lt;/li&gt;    &lt;li&gt;Transactions &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 2: Coupling: Platform, Temporal, &amp;amp; Spatial&lt;/b&gt;    &lt;br /&gt;Loose coupling has become the watchword of complex systems development, yet few understand its multiple dimensions. In the module we&amp;#8217;ll be covering the three different dimensions of coupling as well as patterns for dealing with them.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Platform Coupling &amp;#8211; XML/SOAP &lt;/li&gt;    &lt;li&gt;Temporal Coupling &amp;#8211; Synchronous/Asynchronous &lt;/li&gt;    &lt;li&gt;Spatial Coupling &amp;#8211; Endpoints/Topics &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 3: Asynchronous Messaging Patterns&lt;/b&gt;    &lt;br /&gt;Although scalability is achieved through the use of asynchronous message passing, more advanced message exchange patterns are required to handle today&amp;#8217;s complex integration scenarios. This module will cover the most commonly used patterns:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;One way &lt;/li&gt;    &lt;li&gt;Correlated Request/Response &lt;/li&gt;    &lt;li&gt;Publish/Subscribe &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 4: Bus &amp;amp; Broker Architectural Styles&lt;/b&gt;    &lt;br /&gt;Enterprise Service Buses are all the rage these days. In this module we&amp;#8217;ll be covering what&amp;#8217;s the difference between the Bus architectural style, and the more well-known Broker, found commonly in many EAI projects. Topics will include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Architectural advantages and disadvantages &lt;/li&gt;    &lt;li&gt;Technological advantages and disadvantages &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 5: SOA Building Blocks&lt;/b&gt;    &lt;br /&gt;One of the goals of SOA is to develop systems which are more closely aligned with Business. In this module we&amp;#8217;ll be covering an analysis methodology from moving from the business domain to executable systems that comply with all the principles of loose-coupling.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Business Services &lt;/li&gt;    &lt;li&gt;Business Components &lt;/li&gt;    &lt;li&gt;Autonomous components &amp;amp; Queues &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 6: Scalability and Flexibility&lt;/b&gt;    &lt;br /&gt;In order to enable agility, services must be able to scale up, out, and down quickly. In this module we&amp;#8217;ll see how autonomous components can be configured including transactional and durable aspects of message handling.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Configuring autonomous components &lt;/li&gt;    &lt;li&gt;Scaling up and out &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 7: Long running processes&lt;/b&gt;    &lt;br /&gt;The distributed communications patterns wouldn&amp;#8217;t be complete without a discussion on orchestration. In this module we&amp;#8217;ll see how to manage the state of long-running distributed communication flows as well as:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Encapsulating process logic &lt;/li&gt;    &lt;li&gt;Advantages &amp;amp; disadvantages of orchestration &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 8: Service / Autonomous Component Solutions&lt;/b&gt;    &lt;br /&gt;As developers go to implement autonomous components, guidance is required as to which concepts need to implemented in which project, what dependencies are there between projects, and how to bridge the worlds of messaging, business logic, and reporting. Topics include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Messages + Handlers &lt;/li&gt;    &lt;li&gt;Databases &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 9: Service Layer &amp;#8211; Domain Model Interaction&lt;/b&gt;    &lt;br /&gt;Logic-rich services require the use of advanced techniques for logic componentization. The Domain Model Pattern enforces a high level of Separation of Concerns, yet it must eventually be connected with Service Layer code that supports many concurrent users. In this module, the topics covered will include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Domain Model introduction &lt;/li&gt;    &lt;li&gt;Testing Domain Models &lt;/li&gt;    &lt;li&gt;Optimistic, Pessimistic, and Realistic Concurrency Models &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 10: Creating High-Performance Domain Models&lt;/b&gt;    &lt;br /&gt;The strong separation between the Domain Model and the database which stores and retrieves its data may enable a high level of testability, yet often causes performance problems. In this module, we&amp;#8217;ll see the various aspects impacting the performance of persistence:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Transactions and Isolation Levels &lt;/li&gt;    &lt;li&gt;Lazy Loading, Eager Fetching &lt;/li&gt;    &lt;li&gt;Databases Tips &amp;amp; Tricks &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 11: Web Services and User Interfaces&lt;/b&gt;    &lt;br /&gt;The ease of interacting with users over the web drives the need for service to UI interactions. Also, many integrations require exposing synchronous web services to customers. In this module, we&amp;#8217;ll see what is required in both cases:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;ASP.NET 2.0 Asynchronous Tasks &lt;/li&gt;    &lt;li&gt;Rich Internet Applications and Services &lt;/li&gt;    &lt;li&gt;Web Services for integration &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 12: Smart Client / Service Interaction&lt;/b&gt;    &lt;br /&gt;The publish/subscribe semantics with which services communicate require smart clients to perform a great deal of background work. Also, certain service contracts lead to more performant clients. In this module, we&amp;#8217;ll cover the first part of these interactions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Multi-threaded client challenges &lt;/li&gt;    &lt;li&gt;Client-friendly Service Contracts &lt;/li&gt;    &lt;li&gt;Service Agents and Client Repositories &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 13: Notifications &amp;amp; Smart Clients&lt;/b&gt;    &lt;br /&gt;After Message Handlers in the Service Layer create or update the relevant Model objects in the client Repository, Supervising Controllers are in charge of getting Views to show the updated data. In this module, we&amp;#8217;ll describe the parts and interactions of these flows:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Client-side Model Objects &lt;/li&gt;    &lt;li&gt;Supervising Controllers &lt;/li&gt;    &lt;li&gt;Views and their Interfaces &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Module 14: Commands &amp;amp; Smart Clients&lt;/b&gt;    &lt;br /&gt;Capturing user intent and synchronization between views are at the core of smart clients. After describing solutions that use Events on the View Interfaces, the Command Pattern will be introduced to further decrease coupling between Supervising Controllers. In this module, we&amp;#8217;ll describe the parts and interactions of these flows:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;View Interfaces, and how Entity Cloning affects them &lt;/li&gt;    &lt;li&gt;Supervising Controllers and clone reconciliation &lt;/li&gt;    &lt;li&gt;Commands, and Event-Based programming &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Summary &amp;amp; Review&lt;/b&gt;    &lt;br /&gt;In order to make sure that attendees are able to put into practice all that they&amp;#8217;ve learned throughout the course, here we strengthen the seams between the various topics. Q&amp;amp;A is also a core part of this final section.&lt;/p&gt;  </description><link>http://rhysc.blogspot.com/2010/01/udi-dahan-advanced-distributed-systems.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7806605514179331942.post-8208915281122397503</guid><pubDate>Thu, 24 Dec 2009 02:56:00 +0000</pubDate><atom:updated>2009-12-23T19:09:29.721-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Dependency Injection</category><category domain="http://www.blogger.com/atom/ns#">SOA</category><category domain="http://www.blogger.com/atom/ns#">Wcf</category><title>Relearning WCF</title><description>Of late I have been playing with WCF again. We have some projects here at work that require some integration and we are desperately trying to move away from the old ASMX based services. Unfortunately because I have not touched WCF the whole time I have been here (12 months now, wow! That has gone fast!) and I have found myself at a point where I really need to relook at WCF again and basically relearn it... oh well.&lt;br /&gt;Anyway here is a bunch of stuff that here, that at work we have found to be useful that you may not otherwise be able to do with ASMX or may not be aware you could do with WCF.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;IOC and WCF&lt;/h3&gt;&lt;br /&gt;You can in fact use IoC with WCF, there are some good blog &lt;a href=&quot;http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/07/29/integrating-structuremap-with-wcf.aspx&quot;&gt;posts&lt;/a&gt; and accompanying &lt;a href=&quot;http://dimecasts.net/Casts/CastDetails/150&quot;&gt;videos&lt;/a&gt; to show what to do and if, like me, you just want one ready to that uses the CSL then &lt;a href=&quot;http://twitter.com/thecodejunkie&quot;&gt;The Code Junkie&lt;/a&gt; has done it for you!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Dynamic KnownType Resolution&lt;/h3&gt;&lt;br /&gt;This always erked me that I had to put into the data contract that I knew of other types, it was like really bad tight coupling*. There are a bunch of way to declare known types with the bottom example seeemingly a little known alternative : a provider mechanism&lt;br /&gt;&lt;h4&gt;in config &lt;/h4&gt;&lt;br /&gt;&amp;lt;system.runtime.serialization&amp;gt; &amp;lt;dataContractSerializer&amp;gt; &amp;lt;declaredTypes&amp;gt;...&lt;br /&gt;&lt;h4&gt;Data contract with attributes &lt;/h4&gt;&lt;code&gt;&lt;br /&gt; [KnownType(typeof(PurchaseApprovalRequest))]&lt;br /&gt; [DataContract]&lt;br /&gt; public class ApprovalRequest&lt;br /&gt; {...&lt;/code&gt;&lt;br /&gt;&lt;h4&gt;Knowntype provider&lt;/h4&gt;&lt;br /&gt;The way I have just found out is by declaring a knowntype provider on the service contract:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[ServiceKnownType(&quot;GetKnownTypes&quot;, typeof(ApprovalRequestKnownTypesProvider))]&lt;br /&gt;[ServiceContract]&lt;br /&gt;public interface IApprovalService&lt;br /&gt;{...&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;with the following class (change the implementation to suit yourself, this is from some of my demo code, it’s not recommended!)&lt;br /&gt;&lt;code&gt;&lt;br /&gt;internal static class ApprovalRequestKnownTypesProvider&lt;br /&gt;    {&lt;br /&gt;        public static IEnumerable&amp;lt;Type&amp;gt; GetKnownTypes(ICustomAttributeProvider provider)&lt;br /&gt;        {&lt;br /&gt;            // collect and pass back the list of known types&lt;br /&gt;            foreach (var module in Assembly.GetExecutingAssembly().GetLoadedModules())&lt;br /&gt;            {&lt;br /&gt;                foreach (var knownType in module.FindTypes(&lt;br /&gt;                    (t, f) =&amp;gt; ((Type)f).IsAssignableFrom(t), typeof(ApprovalRequest)))&lt;br /&gt;                {&lt;br /&gt;                    yield return knownType;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;With these two little nuggets I have been able to produce a pretty handy little broker service that act as a very basic content based router that keeps the client messages very clean and does not expose any implementation details (i.e. no passing of service or workflow names in the message header!)&lt;br /&gt;&lt;br /&gt;*NB: to &lt;a href=&quot;http://stackoverflow.com/questions/771560/how-do-you-configure-wcf-known-types-programmatically&quot;&gt;paraphrase&lt;/a&gt; &lt;a href=&quot;http://twitter.com/kkozmic&quot;&gt;Krzysztof&lt;/a&gt;: &quot;Polymorphism is an OO term, not SOA term, so I don&#39;t use it, and make my contracts explicit wherever possible.&quot; be wary that you are using known types for the right reasons</description><link>http://rhysc.blogspot.com/2009/12/relearning-wcf.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item></channel></rss>