tag:blogger.com,1999:blog-71706139744574748222016-12-03T14:49:59.508+10:00Nootn.com.auWeb Technology and Software Development SpecialistAndrew Newtonnoreply@blogger.comBlogger14125tag:blogger.com,1999:blog-7170613974457474822.post-13557990937919166362016-03-17T15:15:00.002+10:002016-03-17T15:17:29.518+10:00A Different Definition of Agile Software Projects"Agile" must surely be the most used (and abused?) buzzword ever in Software Development circles!&nbsp; But what does it really mean?&nbsp; <br /><br />I don't think there is a single correct definition, but I can explain what it means to me and why just to give you another perspective.&nbsp; I have formed this opinion after reading and listening to many other people's opinions (such as <a href="http://jurgenappelo.com/" target="_blank">Jergen Appelo</a>) but reworded it so that it makes sense to me and helps me realize some actual benefits from the concept.&nbsp; Please feel free to leave comments if you agree or disagree because the reason for writing this up is to see if it resonates with other people or if you think I am way off track.<br /><blockquote class="tr_bq">To me, if a Software Project is considered to be "agile" it means that all the stakeholders are <i>happy </i>and if they become <i>unhappy</i>, they are made <i>happy</i> again in a timely fashion. <br /><i><b>nootn.com.au - 2016</b></i></blockquote><br />What?&nbsp; Happiness?&nbsp; Let me explain from a couple of different perspectives.&nbsp; If you don't feel like reading the whole text maybe just skim the "TL:DR" sections in <i>italics </i>to get the gist of what I am talking about.<br /><br /><h3>Customers/Clients/Product Owners/Project Managers *</h3><span style="font-size: x-small;"><i>*I will refer to all the types of people listed as just "client" for simplicity - it may be any or all of the above in your scenario.&nbsp;</i></span><br /><br /><i>TL:DR - Trying to be "Agile" may encourage us to rush into things and not think about longer term goals. Ensure that the client is going to be "happy" in the long run not just getting them short term happiness that may turn into unhappiness later. </i><br /><br />I think where some definitions of "Agile" fall short is they elude to the fact you need to please the customer, but try to be too specific about the "software" aspect.&nbsp; For example definitions along the lines of "Agile means being able to implement changes and new features quickly without breaking things" don't really explain why that is important, or if it really is all the time.&nbsp; It is very specific to the quality of the code base - ways to achieve that are having high <a href="http://www.nootn.com.au/2014/01/code-coverage-with-opencover-example.html" target="_blank">code coverage</a> and robust software architecture following the SOLID principles for example.&nbsp; This is great, but it doesn't necessarily address any aspects of the Software Development Process or that particular project being "Agile", just the code base.<br /><br />A common request from a client might be "I want this new feature in our app quick because our competitor is talking about introducing it soon".&nbsp; If you are blindly trying to be "Agile" you might throw that on the top of your backlog and work on it in the next sprint.&nbsp; This might make the customer temporarily "happy" because they feel like they will not be lagging behind, but they might lose sight of the bigger picture or other lost opportunities.&nbsp; If you have an agile process, it might involve taking the time to do it better than the competitor and making sure something else more important that will get longer term goals does not drop off the list, or blow out the budget.&nbsp; If your process can ensure that the best long term outcome may be achieved by not rushing into that feature request, and you can explain that to the customer, then they may end up still being happy in the short term, but also in the longer term.&nbsp; You may be "Awesomely Agile" according to my definition by doing nothing more than explaining a feature is a bad idea and not implementing it - if that makes the client happy and longer term keeps them happy then you are Agile!&nbsp; Yay!<br /><br /><h3>Product Team (Developers, Testers, BA's etc)</h3><i>TL:DR - In order to achieve the objective above of keeping the Customers/Clients/Product Owners/Project Managers happy, the team should be happy and remain happy also.&nbsp; If they are unhappy, they are unlikely to be able to keep other stakeholders happy and may drag the project down to a point where it is longer able to be "Agile".</i><br /><i>&nbsp; </i><br />Most projects start out new and exiting and people are generally happy to begin with - so it's only natural that things can go south from there since the bar is raised fairly high to begin with!&nbsp; Initially the team is probably burning through tasks and delivering a lot of benefit in a short time.&nbsp; Everyone on the project team is happy.&nbsp; Then things start to go off the rails.&nbsp; Maybe aspects of the process are not working well, clients are changing their mind and wasting effort or not communicating effectively.&nbsp; A very common one is that code starts to "smell" as we rush things and make changes so we quickly end up with a lot of technical debt.&nbsp; If nothing is done about this then even if the team can keep the client happy in the short term, it's unlikely that can continue for long.<br /><br />Unhappy and unmotivated team members are far less likely to be productive, thus not able to implement changes as quickly, keep code quality as high or have great ideas to improve things.&nbsp; The very fact that "retrospectives" or similar concepts are encouraged in documented "Agile" methodologies makes this very obvious.&nbsp; I find generally everyone kind of knows this, but the real problem lies in the fact it's difficult to address it.&nbsp; I am sure you will agree it can be very difficult on any project to get time allocated to removing technical debt.&nbsp; This is generally a cost to the client for no perceived benefit (if you can't explain the benefits effectively).&nbsp; I am hoping a definition like the one described above can help people out with this.&nbsp; Basically we need to explain "in order to keep you happy and thus keep this project <i>agile</i> long term, we need to spend some time making sure the team is happy".<br /><br /><h2>Why do we care about being Agile? </h2>OK so you have read down to here.. or skipped if you got bored.&nbsp; Anyhow why do we care about this buzzword and all seem to want to aspire to what it seems to promise?<br /><br />The purpose of being agile is not to win some sort of competition or think your Software Product is better than some other because it's "more agile".&nbsp; There is no value in comparing "agile" across Products or Teams.&nbsp; The only value in measuring the "agility" of a product is so that you can identify areas to improve it to make more stakeholders happier in a more timely fashion.&nbsp; If you can do this over time for a long period, then you would see a far better outcome than if you let things go off the rails and people are not happy.<br /><br />Another perspective forgetting about clients and money etc is that all stakeholders involved in a project are generally spending time that they could be doing something else - maybe performing some other role or spending time with their family.&nbsp; We owe it to ourselves and each other to make sure working on software projects is an enjoyable experience so that we are not wasting our lives being unhappy at work!<br /><br /><h3>Measuring Agility</h3>By the definition above, in order to try and measure how agile a project is, you are going to have to rely on qualitative measures that involve people's opinions.&nbsp; If anyone has a better way of doing this other than "survey's" then let me know!&nbsp; Here is one relevant survey I found that may be a good starting point:<br /><a href="http://teammetrics.apphb.com/">http://teammetrics.apphb.com/</a><br /><br />For the most part I am not really interested in "measuring" it, just knowing when things are starting to go off the rails so I can try to bring them back on.&nbsp; That can usually be done by talking to people and identifying any potential issues.<br /><br /><br />Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-15463902699226954722014-04-08T14:53:00.002+10:002014-04-08T15:06:37.224+10:00Yet another blog post on how to validate email addressesI have read a lot of blog posts and <a href="http://stackoverflow.com/" target="_blank">Stack Overflow</a> answers over the years on "the best way to validate an email address". &nbsp;This article uses the example of validating in ASP.NET MVC but the theories could apply to any code base.<br /><br />What I have learnt is that like most things, there is no "best" way, it depends on your requirements.<br /><br />So I thought I would outline my most common requirements and how I do it. <br /><br />Usually my requirements for capturing an email address are:<br /><br /><ol><li>Let the user know if they have possibly not typed in an email address at all (E.g. maybe they accidentally put their name in the email field). &nbsp;This should be done client side so it is fast.</li><li>I want the email validation to be as "loose" as possible, not check every known variation. &nbsp;<i>However</i>, I want my mail sending code to work. &nbsp;I don't want to queue up an email task on a background process for it to not be able to deal with the email address supplied.</li><li>Optionally (not always), I want to know that someone actually got the email</li></ol><div>(<i>NOTE</i>: High Performance is not a requirement - this is for validating emails as a user enters them, not batch validating. &nbsp;So I am not worried about overhead of Regex vs String.Contains or anything like that)</div><div><br /></div><div>To meet requirement #1, Regex works. &nbsp;Basically I just want to know they typed <i>something</i> then the @ symbol and then something else to prevent "accidental entry". &nbsp;Nothing more than that. &nbsp;Regex is nice because you can easily apply the same logic on the server and client side. &nbsp;This means the check to make sure it is possibly an email address can happen in the browser without even hitting the server. &nbsp;One .NET Regex pattern for checking <i>something@something</i> is: "<b>.+\@.+$</b>" (<i>please let me know in the comments if there is a better way</i>).</div><div><br /></div><div>For requirement #2, I do not use Regex. &nbsp;Sure there are Regex patterns that claim to validate email "as per the spec" - but I am sure most email clients don't support a lot of those addresses and who knows if everyone actually implements as per the spec. &nbsp;At the end of the day, I want to use the mechanism that is going to send my email to validate my email now, so I know it won't fail validation later. &nbsp;If you are using a third party service to send emails, see if they have a validation service you can call. &nbsp;If you are just using the built in System.Net.Mail namespace, you can verify with the "MailAddress" class. &nbsp;In ASP.NET MVC, this is an example of a Model class with the Regex, plus checking that "System.Net.Mail.MailAddress" thinks that the address is valid:</div><script src="https://gist.github.com/nootn/10091198.js"></script> <br /><div><br />For requirement #3, you could in theory try to check for a "bounce" - but that will not work in all scenarios. &nbsp;Read receipts are also not reliable as the user has the option to not send one and not all mail clients support them. &nbsp;If you really need to know if someone got the email, the only way I can think of is to put a link in there that they have to click to let you know. &nbsp;They are not always going to click it either, so they might need some incentive. &nbsp;A common example is when someone signs up to a service, in the email you put "click here to activate your account". &nbsp;If they never click it, their account is never enabled.<br /><br />Hopefully if you have the same requirements as this then these ideas will help you to quickly implement your email validation without researching options for hours and testing Regex patterns!</div>Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-53814180498213431892014-01-21T13:00:00.003+10:002014-04-08T15:06:08.948+10:00Code Coverage with OpenCover - example with NUnit (can run in TeamCity also)I am a fan of <a href="http://en.wikipedia.org/wiki/Code_coverage" target="_blank">code coverage</a> as long as you aim for 100% coverage "of code that should be tested". &nbsp;I don't think you will get some of the benefits of code coverage if you just turn it on for all code and say "let's aim for 80%". &nbsp;A good code coverage tool should allow you to specify what to include or ignore by namespace, class name and even attributes (such as the "GeneratedCode" attribute).<br /><br /><a href="https://github.com/sawilde/opencover" target="_blank">OpenCover</a> is a nice code coverage tool as it meets these needs and it's Open Source. &nbsp;Later in this post I will go over how to set it up just using batch files to keep it nice and simple.<br /><br />I use code coverage to set myself goals so I know what I am aiming to test in a certain time period. &nbsp;For example, I could say "by the end of the week I want to have all my MVC Controllers tested" - so I add a filter to include the controllers in the code coverage report. &nbsp;So I use it as a way of "<a href="http://www.nootn.com.au/2012/03/time-management-tip-define-success.html" target="_blank">defining success</a>" while writing tests.<br /><br />Keep in mind that having 100% coverage on some code&nbsp;does not mean you have tested all scenarios! &nbsp;All it does is prove you have tested one scenario down that path. &nbsp;So I use it as an <i>indicator </i>of whether something has been tested, not a <i>measure </i>to say the code works in every scenario. &nbsp;But that is a lot better than nothing and accidentally missing some code!<br /><br /><h2>Example implementation - Local Development Machine</h2><h3>Sample Application</h3><div>To test the steps I am documenting here, I have created a very simple sample application. &nbsp;If you want to play with this before adding it to your project or just see how it works, you can download the sample application here: <a href="https://github.com/nootn/OpenCoverExample">https://github.com/nootn/OpenCoverExample</a>.</div><div><br /></div><h3>Basic Setup with NUnit</h3><div>For these instructions, I assume you have a Test project with some NUnit tests already succeeding.</div><br /><ol><li>Install the following NuGet packages (it does not matter which project you install them in as they go to the solution level packages):</li><ol><li>NUnit.Runners</li><li>OpenCover</li><li>ReportGenerator<br />*<i>Take note of the version numbers of each of these packages that were installed as you need them later*</i></li></ol><li>Create a batch file in the root folder of your Test project called "_RunCodeCoverageInOutput.bat"</li><li>In the contents, add the following (replacing 'ProjToTest'; with your project's name, 'TestProj' with the name of your test project, and changing the version numbers to match that of the packages you downloaded:<br /><br /><span style="font-family: Courier New, Courier, monospace;">"..\..\..\packages\OpenCover.4.5.2316\OpenCover.Console.exe" -target:"..\..\..\packages\NUnit.Runners.2.6.3\tools\nunit-console.exe" -targetargs:"/nologo <b>TestProj</b>.dll /noshadow" -filter:"+[<b>ProjToTest</b>]<b>ProjToTest</b>*" -excludebyattribute:"System.CodeDom.Compiler.GeneratedCodeAttribute" -register:user -output:"_CodeCoverageResult.xml"<br /><br />"..\..\..\packages\ReportGenerator.1.9.1.0\ReportGenerator.exe" "-reports:_CodeCoverageResult.xml" "-targetdir:_CodeCoverageReport"</span></li><li>Go to the properties of the batch file in Visual Studio and change the value of "Copy To Output Directory" to "Copy if newer"</li><li>Build your solution, go to the output directory (E.g. bin\debug\) and run the batch file "_RunCodeCoverageInOutput.bat"</li><ol><a href="http://4.bp.blogspot.com/-zx716c6_73o/Ut3S3_tILQI/AAAAAAAAAPc/CTGXWzH5Ch8/s1600/OpenCoverExampleReport.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><br /></a><li>If it doesn't work - check the console output to diagnose the error - feel free to comment on this post and I will try to help, or <a href="https://github.com/OpenCover/opencover" target="_blank">refer to the documentation</a>.&nbsp;</li><li>If it does work, you should have a subdirectory created called "_CodeCoverageReport" and in there, open up "index.htm" which shows your nicely generated code coverage report!<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-zx716c6_73o/Ut3S3_tILQI/AAAAAAAAAPc/CTGXWzH5Ch8/s1600/OpenCoverExampleReport.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img alt="Code Coverage Report Example" border="0" src="http://4.bp.blogspot.com/-zx716c6_73o/Ut3S3_tILQI/AAAAAAAAAPc/CTGXWzH5Ch8/s1600/OpenCoverExampleReport.jpg" height="306" title="Code Coverage Report Example" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">You can drill into each of the items on the left to see which lines of code have/have not been run</td></tr></tbody></table></li></ol></ol><h3>Include or Exclude more</h3><span style="font-family: inherit;">To include or exclude more namespaces, you just alter the "filter" value. &nbsp;The example filter I have above is&nbsp;"+[<b>ProjToTest</b>]<b>ProjToTest</b>*"&nbsp;which means "assembly = ProjToTest, namespace = ProjToTest". &nbsp;If for example you had a particular namespace within that you wanted to exclude, you could add a "-" to the filter after the "+", E.g:&nbsp;</span>"+[<b>ProjToTest</b>]<b>ProjToTest</b>*<b> -[ProjToTest]ProjToTest.SomeNamespace*</b>". &nbsp;This illustrates you can be very granular by only including certain namespaces, or just include all then exclude specific ones - choose which ever option saves you time and makes sense.<br /><br />There can be cases where auto-generated code ends up in namespaces you want to include, but you don't want to have the generated code included. &nbsp;An example of this is <a href="http://t4mvc.codeplex.com/" target="_blank">T4MVC</a> which generates code for your MVC project to create strongly typed references where you usually need to use magic strings. &nbsp;One way I found around this which is included in the batch file above is to use the "excludebyattribute" switch. &nbsp;You will notice above I have put&nbsp;-excludebyattribute:"System.CodeDom.Compiler.GeneratedCodeAttribute" which works if the generated code has that attribute (as T4MVC does).<br /><br />For a more complicated example, see the code coverage I have created for the <a href="https://github.com/nootn/DotNetAppStarterKit" target="_blank">DotNetAppStarterKit</a> sample MVC app:&nbsp;https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc.UnitTests/_RunCodeCoverageInOutput.bat.<br /><br /><h3>Running in TeamCity with No TeamCity Changes</h3>I couldn't find a TeamCity add-on for OpenCover (there was one for PartCover built in) and the <a href="http://scubamunki.blogspot.com.au/2011/10/adding-opencover-to-teamcity.html" target="_blank">only instructions I could find</a> to get it working involved installing things on the server. &nbsp;So that was another good reason to get this working as a batch file (so it can run in TeamCity self-contained within it's own source code).<br /><br />This is how I got it working (using TeamCity version 7 at the time of writing) with the Code Coverage report showing as an "Artifact" so I can just click the link in TeamCity to view it:<br /><br /><ol><li>Create another batch file similar to "_RunCodeCoverageInOutput.bat" above called "_RunCodeCoverageInTeamCity.bat", but remove the "..\..\..\" in front of any executables, because TeamCity will run it from the root level, not have to go up 3 levels (you might have to play with this depending how TeamCity is configured for you)</li><li>Again make the batch file "Copy if newer" as above</li><li>In TeamCity, make sure your Artifact Path includes "_CodeCoverageReport":<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-4sce9yYf6cQ/Ut3b5HCSU4I/AAAAAAAAAPs/-pUNStskiTQ/s1600/OpenCoverTeamCityArtifact.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img alt="Code Coverage Team City Artifact Path" border="0" src="http://3.bp.blogspot.com/-4sce9yYf6cQ/Ut3b5HCSU4I/AAAAAAAAAPs/-pUNStskiTQ/s1600/OpenCoverTeamCityArtifact.jpg" height="76" title="Code Coverage Team City Artifact Path" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><br /></td></tr></tbody></table></li><li>Make a new build step after your solution is built to run the code coverage batch file. &nbsp;It can just be a "Command Line" runner type and it just needs to run the batch file you created:</li></ol><div><a href="http://4.bp.blogspot.com/-NL8Ic0BzrX8/Ut3cJnjW_zI/AAAAAAAAAP0/oAcQ-Pk4gQ4/s1600/OpenCoverTeamCityBuildStep.jpg" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img alt="Open Cover Team City Build Step" border="0" src="http://4.bp.blogspot.com/-NL8Ic0BzrX8/Ut3cJnjW_zI/AAAAAAAAAP0/oAcQ-Pk4gQ4/s1600/OpenCoverTeamCityBuildStep.jpg" height="451" title="Open Cover Team City Build Step" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><br />Hopefully this helps you get started on your Code Coverage journey!<br /><br />Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-20611575474286277562013-03-25T20:42:00.002+10:002013-03-25T20:42:37.460+10:00Command Query Separation to better manage Async and Caching for PerformanceI have done a fair bit of reading and experimenting with a concept people call "CQS" or "CQRS". For a good discussion about the possible difference see <a href="http://codebetter.com/gregyoung/2009/08/13/command-query-separation/">Greg Young's post</a>. From here on in I am going to assume they are the same thing for simplicity.<br /><br />I am not going to do an in depth post about why you should or should not use this pattern/concept, I will only provide an overview. I am however going to show you one common application where I have found it brings great benefits using an ASP.NET MVC Web Application which relies heavily on server side caching of data and async controllers.<br /><br /><a name='more'></a><br />All the code in this article is on <a href="https://github.com/nootn/DotNetAppStarterKit">Github</a> and some of the usable components are available in the following NuGet packages:<br /><br /><ul><li><a href="http://nuget.org/packages/DotNetAppStarterKit.Core/">DotNetAppStarterKit.Core</a></li><li><a href="http://nuget.org/packages/DotNetAppStarterKit.Web/">DotNetAppStarterKit.Web</a></li><li><a href="http://nuget.org/packages/DotNetAppStarterKit.Web.Mvc/">DotNetAppStarterKit.Web.Mvc</a></li></ul><br />In case you do not want to research elsewhere, the main reason to use CQS/CQRS is to follow the <a href="http://www.oodesign.com/single-responsibility-principle.html">single responsibility principle</a>. Benefits&nbsp;include&nbsp;more modular, testable code.<br /><br />The only argument I can find against using CQS/CQRS seems to be that in some cases it might over-complicate the solution. This would in theory make the code less maintainable for a developer who was not familiar the pattern or found it a bit abstract. In my experience, I have never been asked to build a pure CRUD application with no extra bells and whistles, so I struggle to think of an example where this would not be a good idea when data is involved.<br /><br />One common example to argue CQS/CQRS would not be overkill in a typical web application is the concept of caching. When you cache some data on the server side, you have now introduced a second data source alongside your primary database. At this point, unless you are only doing really simple caching, cache management can become very complicated and error-prone. When you add something to cache, you need to also manage when to remove or update it.<br /><br />Along with caching to improve speed, one performance improvement concept to ensure a more scalable web application is asynchronous server side processing. I recommend doing your own reading on this topic, but in a nut shell: in an ASP.NET web application (MVC or Web Forms) <a href="http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx">there are a limited number of "worker" threads</a> able to process requests. If all of them are in use requests start to queue up and eventually fail if the server cannot handle the load (search for "Asynchronous Pages" if using WebForms, or "Asynchronous Controllers" if using MVC to learn more).<br /><br />When you combine caching and async, it is very easy to implement a poor design. As a general rule: if you are retrieving data from a database or external data source it should be done on a background thread, and if you are retrieving from a local cache it should use the worker thread. As you can imagine when this kind of logic is littered throughout your code, in combination with already complicated cache management code, it can become a real mess very quickly. <br /><br />Time for some code. &nbsp;In a sample app, assume we have a collection of "Thingy's" where a "Thingy" has an ID and a Name. &nbsp;You can add and edit Thingy's. &nbsp;The collection of all Thingys is cached when you get to the screen that lists them. &nbsp;Each individual Thingy is cached when you view it's detail. &nbsp;<i>This is a poor example of a real world application as you would probably not cache the individual items, but for demonstration purposes it allows me to show how this pattern makes cache management cleaner.</i><br /><br />Here is the "ThingysController" that retrieves all the data to display for the list:<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-9MNOfBR4Xic/UUfnXfc92qI/AAAAAAAAAMc/LbThlokwN7c/s1600/ThingysController.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="167" src="http://3.bp.blogspot.com/-9MNOfBR4Xic/UUfnXfc92qI/AAAAAAAAAMc/LbThlokwN7c/s400/ThingysController.png" width="400" /></a></div>(<a href="https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/Controllers/ThingysController.cs">https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/Controllers/ThingysController.cs</a>)<br />You will notice the controller action "Index" is marked with the keyword "async". &nbsp;This does not mean it will always run asynchronously, it will only spawn a new thread if it needs to. &nbsp;If the code takes "Path A" (I.e. the data was retrieved from cache), then it will all happen on one thread. &nbsp;If the code however takes "Path B", then the "ExecuteAsync" method will be processed on a background thread, and a new thread will resume processing the request when it is finished. &nbsp;All the complexity of caching is implemented in the IGetAllThingysQuery implementation and as we will see later some other components.<br /><br />Here is the code for the Query itself that is allowing this controller code to be so simple:<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-M9iTmCfqftM/UUf3_NFfyNI/AAAAAAAAAM0/c7Fjdm8cF2M/s1600/GetAllThingysQuery.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232" src="http://2.bp.blogspot.com/-M9iTmCfqftM/UUf3_NFfyNI/AAAAAAAAAM0/c7Fjdm8cF2M/s400/GetAllThingysQuery.png" width="400" /></a></div>(<a href="https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/DataProject/Query/GetAllThingysQuery.cs">https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/DataProject/Query/GetAllThingysQuery.cs</a>)<br />This query has the "single repsonsibility" of "retrieving all Thingys". &nbsp;Sometimes that is from cache, sometimes it is from the database. &nbsp;You may notice there is a method "missing" - "ExecuteAsync" which the controller is calling. &nbsp;That is created in the "QueryBase" class which just wraps the "Execute" method in a task so it can be called using the "await" keyword. &nbsp;The other thing to note is the event publisher. &nbsp;This class does not have to worry about how to cache the items, it just raises an event and some other object can deal with that. &nbsp;The other object in this case is the "ThingysRetrievedEventSubscriber":<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-W6teJlxgrpg/UU0-IoYFxSI/AAAAAAAAANE/3MyObYP4UYQ/s1600/ThingysRetrievedEventSubscriber.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="148" src="http://1.bp.blogspot.com/-W6teJlxgrpg/UU0-IoYFxSI/AAAAAAAAANE/3MyObYP4UYQ/s400/ThingysRetrievedEventSubscriber.png" width="400" /></a></div>(<a href="https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/DataProject/EventSubscriber/ThingysRetrievedEventSubscriber.cs">https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/DataProject/EventSubscriber/ThingysRetrievedEventSubscriber.cs</a>)<br /><br />The code for "ThingyController" to show one selected Thingy and it's underlying Query and events are very similar so I will leave them out of this post but it is important to note they are both writing to different cache keys when their data is accessed.<br /><br />Now for updating data. &nbsp;Here is the ThingyController method that accepts a POST to update data:<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-Mbf-Xs7Um0s/UVAj3ADiuTI/AAAAAAAAANU/bUv8sf5_Hjo/s1600/ThingyControllerPost.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="163" src="http://3.bp.blogspot.com/-Mbf-Xs7Um0s/UVAj3ADiuTI/AAAAAAAAANU/bUv8sf5_Hjo/s400/ThingyControllerPost.png" width="400" /></a></div>(<a href="https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/Controllers/ThingyController.cs">https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/Controllers/ThingyController.cs</a>)<br />As you can see, the validation is done on the worker thread, however the command to update the data will run on a background thread as demonstrated in the "await" line.<br /><br />Now, the code for the SaveThingyCommand:<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-9U_u1NiEkwE/UVAl0YS9H7I/AAAAAAAAANg/NJOeSHGia4k/s1600/SaveThingyCommand.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="257" src="http://2.bp.blogspot.com/-9U_u1NiEkwE/UVAl0YS9H7I/AAAAAAAAANg/NJOeSHGia4k/s400/SaveThingyCommand.png" width="400" /></a></div>(<a href="https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/DataProject/Command/SaveThingyCommand.cs">https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/DataProject/Command/SaveThingyCommand.cs</a>)<br />The command has the responsibility of saving data if it needs to be saved. &nbsp;It keeps track of what happened so that when it publishes an event, the event subscriber(s) can be clever about how they handle what happened. &nbsp;In this example, if someone saves a Thingy, but they actually did not change anything, then it would be inefficient to clear the cache because nothing has happened. &nbsp;So the "action" in this event is just a concept I came up with, not every command will track this kind of information.<br /><br />Here is the handler of the event published, which closes the loop on how the cached items are removed when a change is made (I.e. the individual item that was updated is removed from cache, but it also clears the full list of the cached items from the "GetAllThingys" query to be safe):<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-l-HLUi_xmK4/UVAnOOePPRI/AAAAAAAAANw/-4jp1MSqHN8/s1600/ThingyChangedEventSubscriber.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="142" src="http://2.bp.blogspot.com/-l-HLUi_xmK4/UVAnOOePPRI/AAAAAAAAANw/-4jp1MSqHN8/s400/ThingyChangedEventSubscriber.png" width="400" /></a></div>(<a href="https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/DataProject/EventSubscriber/ThingyChangedEventSubscriber.cs">https://github.com/nootn/DotNetAppStarterKit/blob/master/DotNetAppStarterKit.SampleMvc/DataProject/EventSubscriber/ThingyChangedEventSubscriber.cs</a>)<br />You could argue that this event subscriber should be split in two - one that handles removing the individual item and one that handles removing the collection of all items. &nbsp;That would be fine and very simple to implement. &nbsp;It depends on what you feel the responsibility of this subscriber should be. &nbsp;In this case I chose to combine since it's such a simple example.<br /><br />It is&nbsp;pertinent&nbsp;to mention that the EventSubscribers in DotNetAppStarterKit will be run on the same thread as the code that published the event. &nbsp;There is no extra threading added. &nbsp;If your event subscriber should run on a separate thread that would be simple to implement. &nbsp;I think this pattern also extends nicely into more complicated scenarios where your event publisher might be a message bus of some kind where the web application fires and forgets, rather than all the code needing to be within the web application.<br /><br />If you struggle to follow the blog post I understand as it's very difficult to explain how this works in writing. &nbsp;I would recommend grabbing a copy of <a href="https://github.com/nootn/DotNetAppStarterKit">DotNetAppStarterKit </a>source code and running up the SampleMvc web application. &nbsp;There is some tracing in there that explains what is going on, or just put some breakpoints in the code and check out what is happening at each stage.<br /><br />I look forward to hearing comments from people on whether they think this is a good approach or if it has some flaws! &nbsp;Hopefully if you like it the <a href="http://nuget.org/packages?q=DotNetAppStarterKit">DotNetAppStarterKit NuGet packages</a> will save you some valuable time.Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-10699261281943794242013-01-15T14:49:00.000+10:002013-01-15T14:49:45.215+10:00Time management tip - "Getting things done" method<br />I was speaking to a couple of people recently about a book I read recently called "Getting things done" by David Allen.<br />(<a href="http://www.amazon.com/Getting-Things-Done-Stress-Free-Productivity/dp/0142000280" target="_blank">http://www.amazon.com/Getting-Things-Done-Stress-Free-Productivity/dp/0142000280</a>)<br /><br />It is a very good read but basically it's a "program" you follow in order to get all your "todo" lists into one place and how to manage your tasks.<br /><a name='more'></a><br />I actually followed the program and was going along swimmingly for a&nbsp;couple&nbsp;of weeks, but if you don't follow it very closely it's easy to slip back into old&nbsp;habits. &nbsp; Even now I am in a state that I am not 100% following it, I am still better off than not following it at all.<br /><br />If you don't feel like reading the whole book I will try to&nbsp;summarize&nbsp;in my words what I got out of it - what I say below may not be what the book was trying to get across, it's my interpretation. &nbsp;If you have read it and got something else out of it please add a comment so we can learn from&nbsp;each other.<br /><br />Basically, if you have things you need to do "in your mind", you will constantly be thinking about them at times when you should be doing something else - they will drift in and out of your consciousness which increases your stress levels.<br /><br />In order to feel at ease with all the tasks you need to do (no matter how many you have), they all need to be documented, not in your head. &nbsp;Until you have them on a list and all out of your head, they will keep popping back into your head and you will be stressing about them. &nbsp;If they are on a list and you can trust they are all on the list, then your mind can be free (at least for a while or at times - you can more easily be "<a href="http://en.wikipedia.org/wiki/Mindfulness" target="_blank">mindful</a>" in some situations when these extra thoughts are not lingering).<br /><br />You should manage work and personal tasks the same way - they are all just things you need to do, so don't manage them differently (they can go on different lists, but how you manage those lists should be consistent).<br /><br />When you have a "todo" list, you actually need to have a "next actions" list as well as a high level list of things to do. &nbsp;If you just have high level "tasks" to do, then you will keep skimming over them thinking "oh yeah, I will do that one day".. but if you actually write down a very specific "next action" such as "ring person x", then when you scan your list for things to knock off, it's much more achievable and you don't get distracted by the bigger more daunting "project". &nbsp;You still need the high level list of "projects", but you can just go through that maybe once a week and figure out for each one what the next action is if you don't already have one.<br /><br />It is not feasible to work on tasks in "highest priority first" - it just doesn't work and I am sure everyone has found this out. &nbsp;There are 4 factors to consider when trying to determine what to do next:<br /><ol><li>Context/location</li><li>Time available</li><li>Energy available</li><li>Priority</li></ol><br />So it makes sense to divide your "next action" list up into categories such as "At Work - On Computer", "At Work - No Computer", "At Home - On Computer", "At Work - No Computer". &nbsp;So the first thing you look at when determining something to do is "can I physically do this where I am, with the equipment I have?". <br /><br />Next you see if you have enough time to do it, then whether you have the energy to do it and finally all other things being equal you look at the priority.<br /><br />One thing I found that the book does not describe is that sometimes you need to plan to have the time and energy and be in the right place to get the high priority things done.. otherwise they never get done! (E.g. block out 2 hours in your outlook calendar to complete some task and let nothing distract you from that)<br /><br />You need to have your "list"/"lists" with you at all times because as soon as you think of something you need to get it in there. &nbsp;When I started I was using <a href="http://gmail.com/" target="_blank">Google Tasks</a>. &nbsp;It is a feature within Gmail where you can track multiple lists of tasks, and tasks can have heirarchys. &nbsp;I had an app on my phone (GTasks) which sync'd with my Google Tasks list, so that if I was out and about, at work or at home I always had my list with me because I could access it from any PC or my phone.<br /><br />After a while I moved over to <a href="http://workflowy.com/" target="_blank">Workflowy</a> just due to my own personal preference using that one (I like&nbsp;categorizing&nbsp;using&nbsp;hash-tags&nbsp;because it makes it a bit more like a mind map than just a bunch of lists). &nbsp;Workflowy works on any internet connected device with a web browser so there is nothing to install and is free up to a certain amount of data/usage.<br /><br />I hope that helps give you some tips even if you don't read the book.. or like me read the book but don't quite follow the rigid process!Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com1tag:blogger.com,1999:blog-7170613974457474822.post-84519799425399716802013-01-15T01:17:00.000+10:002013-02-05T21:29:07.089+10:00Run PowerShell from .NET program without System.Management.AutomationI have run into the problem a couple of times where it's not "easy" to add a reference to System.Management.Automation in order to execute PowerShell scripts from .NET code. &nbsp;I found a way around it which works for simple scenarios where you might just want to execute some script and read the standard output plus error output.<br /><br /><a name='more'></a>System.Management.Automation can be an issue because you may need to install a Windows SDK in order to get the DLL on your machine (<a href="http://stackoverflow.com/a/1187978/281177" target="_blank">http://stackoverflow.com/a/1187978/281177</a>). &nbsp;Then there can be versioning issues also. &nbsp;One workaround seems to be to hack the csproj file to just reference it and hope that Visual Studio knows what to do, for example this solution:&nbsp;<a href="http://stackoverflow.com/a/1372061/281177" target="_blank">http://stackoverflow.com/a/1372061/281177</a>.<br /><br />Here is some sample code on how to execute a PowerShell script and get the error plus standard output from it using System.Management.Automation:<br /><script src="https://gist.github.com/nootn/4713862.js"></script> An alternative is to write some simple code that just executes a batch file, where the batch file kicks off running PowerShell, and take one argument which is the batch file to run:<br /><script src="https://gist.github.com/nootn/4713857.js"></script> The batch file can either run the default PowerShell detected:<br /><script src="https://gist.github.com/nootn/4713847.js"></script> Or you could try and force it to use a particular "powershell.exe" version by specifying a full path:<br /><script src="https://gist.github.com/nootn/4713855.js"></script> <br /><hr /><b><u>DISCLAIMER</u></b>: I only tested this on a very simple scenario and it was a quick way around the problem. &nbsp;I would be interested to know if you end up using this scenario how it goes for you. &nbsp;Please leave a comment!<br /><hr />Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com2tag:blogger.com,1999:blog-7170613974457474822.post-5854846933459572402013-01-14T21:51:00.000+10:002013-01-14T21:51:20.019+10:00Side Project: Website for MillinerI built a web presence for a client who creates custom millinery, mostly headwear and some jewellery. &nbsp;She had a business card and a facebook page but that was it.<br /><br /><a name='more'></a>The website requirements were to be simple and easy to edit and maintain, add custom image collections, news and events including photos of the events, facebook integration (like button and link to page), testimonials and a contact form. &nbsp;The site had to have a mobile version and desktop version. &nbsp;The design had to compliment the logo and custom polka dots.<br /><br />Here is the end result:<br /><a href="http://www.bronnieg.com/">http://www.bronnieg.com</a>Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-86008774790560915382012-07-10T16:03:00.000+10:002013-02-05T22:01:18.836+10:00Performance Profiling Console (or Win/WPF) Applications<span style="font-size: large;">Performance</span> is a big factor in a successful project - especially in the Health Industry. &nbsp;Clinicians do not want to be waiting for software to run, they are busy saving lives!<br /><br />There is a great tool I am sure most ASP.NET and ASP.NET MVC developers are using called <a href="http://miniprofiler.com/" target="_blank">MiniProfiler</a>. &nbsp;If you are not using it - I highly recommend getting it installed today, even if just in your development environment (although I always have it running in test and production but restrict access to developers and some trusted power users).<br /><br /><a name='more'></a><br /><br />I have recently found the need to write some background processes running as console applications on schedules. &nbsp;Being a background process and not halting any user input, you might ask why I care about profiling these processes. &nbsp;The reason is they get installed on servers along with other critical applications, and if they are constantly churning away in the background, taking up CPU and RAM or chewing up SQL resources, then I believe that will make a noticeable different to the client facing applications somewhere along the line. &nbsp;So it is worth investing the time to make sure they perform OK at least, if not well.<br /><br />There is no great&nbsp;equivalent&nbsp;I have found for MiniProfiler for the Console/Windows/WPF application environment. &nbsp;But there is no reason you can't actually use MiniProfiler in this environment either!<br /><br /><h3> What about MiniProfiler in non-web environments?</h3>It took a bit of mucking around to get this working, so to save time in future I have created a NuGet package called "<a href="http://nootn.github.com/MiniProfiler.Windows/">MiniProfiler.Windows</a>" which helps get up and running a lot quicker. &nbsp;See the page project page at&nbsp;<a href="http://nootn.github.com/MiniProfiler.Windows/">http://nootn.github.com/MiniProfiler.Windows/</a>&nbsp;for a "quickstart" guide.<br /><br />While this process makes it easy to implement MiniProfiler around your code and get a nice formatted output for writing to the console, debug window or log files, it is worth spending the time designing your console application for ease of unit testing and performance profiling. &nbsp;I found the combination of <a href="http://en.wikipedia.org/wiki/Inversion_of_control" target="_blank">IOC</a> and <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming" target="_blank">AOP</a> great for this. &nbsp;Your IOC container supports testable, clean code while AOP supports wrapping MiniProfiler steps around relevant methods, without having to litter your method body with profiling code.<br /><br />There is a demonstration of this in the Git repository for <a href="https://github.com/nootn/MiniProfile">MiniProfiler.Windows</a>. &nbsp;If you fork or download the code, run the "ConsoleApplicationWithIocAndAop" console application for an example, or follow the steps below to get started yourself.<br /><br /><h3> <a href="" name="Steps"></a>Steps to creating a clean, testable console application with performance profiling:</h3><div>These steps make the assumption you will use <a href="http://code.google.com/p/autofac/" target="_blank">AutoFac</a> for IOC and <a href="http://www.simpleaspects.com/" target="_blank">Snap</a> for AOP. &nbsp;You may substitute these for your&nbsp;favorite IOC and AOP frameworks.&nbsp;</div><br /><br />a) First, create a new console application. &nbsp;Ensure you change the target framework to ".NET Framework 4" (not client profile)<br /><br />b) Next, Install NuGet packages "MiniProfiler.Windows" and "Snap.Autofac" (NOTE: at the time of writing this, the Snap.Autofac library had a broken reference to the "fasterflect" library - it was a bit of mucking around to get that working, basically reverting&nbsp;fasterflect back to version 2.0.2 using a manually added reference)<br /><br />c) Now, into the code! &nbsp;You need to register a few things with your IOC container, and if using Snap, also configure some attributes and how they are handled, for example:<script src="https://gist.github.com/nootn/4714028.js"></script><br />There are a couple of key classes here, "ProfileMethodAttribute" is the attribute you put above any method you want to wrap a MiniProfiler step around:<script src="https://gist.github.com/nootn/4714033.js"></script><br />There are a couple of key classes here, "ProfileMethodInterceptor" is the class that does the work to wrap the method call with a MiniProfiler step, using the method name as the step name<script src="https://gist.github.com/nootn/4714037.js"></script>&nbsp;d) Any method that you would like a MiniProfiler step wrapped around, you just need to add a [ProfileMethod] attribute to, and assuming that class was provided by the IOC container, it will just work.<br /><br />e) Finally you can write the main program code. &nbsp;All it should do is start MiniProfiler, run your application logic then stop profiling and get the output:<script src="https://gist.github.com/nootn/4714048.js"></script><br /><br />For the full code example, browse the source at&nbsp;<a href="https://github.com/nootn/MiniProfiler.Windows/tree/master/ConsoleApplicationWithIocAndAop">https://github.com/nootn/MiniProfiler.Windows/tree/master/ConsoleApplicationWithIocAndAop</a>.<br /><br />I hope this gives you some thoughts on how to improve how you write console applications. &nbsp;If anyone would like to provide a code review on the code I have written I would love to know if there is anything wrong or anything that can be improved, please leave a comment or fork me on github!Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-22540472504543843032012-03-05T22:05:00.001+10:002013-01-13T15:49:44.443+10:00Time management tip – Define Success<br />I do not claim to be an expert in time management; I feel that it’s always something I can improve on. &nbsp;However someone at work did comment on the perception that I seem to get a lot done, even though my backlog of work is always huge. &nbsp;I think that perception causes me to get more work as people keep loading it on thinking I am getting through it all – but that is a separate issue!<br /><br />I thought I might try to document some time management tips I consciously use after reading quite a few books and blogs on the topic and trying different techniques myself.<br /><br /><a name='more'></a><br /><br />One tip I found works is to define success. &nbsp;There is a lot of literature from a lot of different backgrounds on this concept, but basically what I have found is if you have some task to complete, it helps to define what the future state will look like when that task is “done”.<br /><br />If you do not define success, you may keep working on a task thinking it could be done better when actually what you have done so far meets or exceeds all the mandatory requirements. &nbsp;There is always more you can do to improve something, but at some point when you have delivered value there might be something more important to work on to deliver more value rather than continuing to refine the current task gaining little value.<br /><br />On the flipside, if you do not define success you might think a task is finished, only to put it in the “done” pile and it comes back to bite you because when you have to add to it or re-do it, the urgency will be greater than it was the first time. &nbsp;This will push other tasks back and increase stress.<br /><br />An example I had recently was when I found out I had some ridiculous deadlines to meet with a Software Development project that got shortened (I had 4 weeks, down to 2). &nbsp;Normally being the manager I am able to assign most development work to my team members and concentrate on architecture and building reusable components. &nbsp;But in this case I had no one to assign it to as they already had priorities, so I had ot do it myself. &nbsp;I came in on a weekend in order to kick start my development – no distractions or interruptions which obviously helped. &nbsp;I had to think what I hoped to achieve on that weekend. &nbsp;Sacrificing family time does not usually go down well with me so I had to make sure it was worthwhile. &nbsp;I had an idea to write up a big email explaining what I had achieved over the weekend at the start of the first day - my goal (or "success criteria") was to be able to send that email by the end of the weekend. &nbsp;I actually drafted the email, put the recipients in so it was ready to go. &nbsp;I clearly outlined the things that I “had achieved” (I.e. was going to achieve). &nbsp;As the weekend wore on, I began working through the items. &nbsp;Some became blocked, and being a weekend I could not contact whoever I needed to get the answers. &nbsp;So I went into my draft email and started a section “Things I could not complete and why”. &nbsp;So my success criteria did change, but I was able to explain why and move on to the next task. &nbsp;Overall this worked out really well as I was motivated to be able to send that email. &nbsp;Everything I worked on was aiming towards that goal. &nbsp;I am sure I got more done as I had a focus and a goal, rather than feeling daunted by the sheer volume of work and not knowing how much I should have been able to get done.<br /><br />Relating this to programming, think of it like doing BDD (Behaviour Driven Development). &nbsp;In BDD you define the scenarios and write tests for a feature first before building the feature. &nbsp;So before you begin to work on a feature you have already thought about (and documented) what should work and what should not work, and hopefully figured out any unknowns. &nbsp;Then when you go to build the feature there are far less questions than if you had just coded away with a lot of unknowns. &nbsp;You also know when to stop – when all your BDD tests “pass”. &nbsp;You will find using BDD properly, although it might seem like more time up front, you should actually save time in rework and/or doing too much on a feature.<br /><br />I hope you try this technique whether you are programming or performing other tasks as I have found it works for both and has made me more productive. <br /><br /><b>Note:</b> If you are doing .NET development I highly recommend <a href="https://bitbucket.org/MehdiK/bddify/wiki/Home" target="_blank">bddify</a>&nbsp;for implementing BDD - it is very simple to get started and is very flexible.<br /><div><br /></div>Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-38904755461101638642011-12-20T13:52:00.000+10:002013-01-13T16:17:05.226+10:00Move TFS 2010 Project Collection Database to Different SQL ServerIf you started using TFS 2010 on a <a href="http://msdn.microsoft.com/en-us/library/dd631899.aspx" target="_blank">single server</a>&nbsp;then you might get to a point where you want to move one or more Project Collection databases off that server. &nbsp;The reaons for that could be improved performance, or that you installed SQL Express and your database hit the <a href="http://blogs.msdn.com/b/sqlexpress/archive/2010/04/21/database-size-limit-increased-to-10gb-in-sql-server-2008-r2-express.aspx" target="_blank">4GB limit (now 10GB)</a>.<br /><br /><a name='more'></a><br /><br />Another common scenario where these steps might be handy is if you're in an environment with Shared SQL Server infrastructure, and your DBA's don't want your TFS account having "sysadmin" access on the server. &nbsp;What you can do is grant your TFS account "sysadmin" access for a few minutes while you configure the server (see Part 1 below), then they can take it away for good. &nbsp;Alternatively you could try give a DBA account TFS Administrator access and get them to follow the steps in Part 1. &nbsp;You can then create Project Collections on your SQL Express instance, and have them moved in a controlled manner using the steps in Part 2 below.<br /><br />I found it difficult to find "easy to follow" instructions on how to move an individual TFS Project Collection database. &nbsp;Some instructions <a href="http://msdn.microsoft.com/en-us/library/ms252516.aspx" target="_blank">show how to move all databases</a> including SharePoint and Reporting Services which makes the instructions complicated if you just want to move one of the databases. &nbsp;So my <b>disclaimer</b> is "<i>this worked for me</i>"! &nbsp;If you do try this yourself and hit any issues or have any questions please leave a comment on this blog post and I will see if I can help.<br /><br /><b><u>Part 1: Prepare the SQL Server Instance for TFS:</u></b><br />This part can actually be the most challenging because you need a service account that is a TFS Administrator, and has "sysadmin" access on the SQL Server box! &nbsp;You better either have really nice DBA's who will temporarily grant your service account "sysadmin" access on the SQL box, or you better be a nice TFS Administrator and prepared to give your DBA's account TFS Administrator access.<br /><br />I went with the "nice DBA" option and got the DBA's to give my TFS service account "sysadmin" access on a SQL box, so I can't confirm whether giving a DBA account TFS Administrator access works but there is no reason it should not.<br /><br />Here are the steps:<br /><br /><ol><li>Choose "Account X" which is already a TFS administrator service account, <a href="http://blog.sqlauthority.com/2008/12/27/sql-server-add-any-user-to-sysadmin-role-add-users-to-system-roles/" target="_blank">grant it "sysadmin" access on the Destination SQL Server</a></li><li>Remote into the TFS Server and fire up a command prompt running as "Account X"</li><li><a href="http://msdn.microsoft.com/en-us/library/ee349267.aspx" target="_blank">Run the "TFSConfig PrepSQL" command</a>&nbsp;passing through the Destination SQL Server Instance name</li><li>Revoke the "sysadmin" access for "Account X" on the Destination SQL Server</li></ol><div>Assuming this works, the server is now ready to host any TFS databases! &nbsp;It seems that command somehow notifies TFS about the SQL Instance as well as SQL Server being "prepared". &nbsp;That is why the account needs such a high level of access on both systems.</div><div><br /></div><div><b><u>Part 2: Move the database and Reconfigure TFS:</u></b></div><div><ol><li>Remote into the TFS Server and open the TFS Admin app</li><li>Stop the Project Collection you are going to move</li><li>Take a full backup of the current Project Collection database</li><li>Restore the Project Collection database to the Destination SQL Server</li><li>Back in the TFS Admin App, edit the Project Collection giving it the Destination SQL Server Instance name and hit "Save" (this took a few minutes for me)</li><li>Bring the Project Collection back online&nbsp;</li></ol><div>I have&nbsp;definitely&nbsp;noticed a massive performance improvement having the Project Collection database running on a high-spec SQL Server Instance rather than the lower-spec single server install that TFS is on.</div></div>Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-7605850698167577632011-12-16T21:12:00.000+10:002013-01-14T21:14:44.500+10:00Side Project: Website for BuilderThe builder who renovated my house wanted to get a web presence. &nbsp;Requirements were to be able to add images into a portfolio, have a contact form, be able to add news etc. &nbsp;Also setting up a custom domain, email addresses and a lot of training material for self management.<br /><div><a name='more'></a>I also set up&nbsp;analytics&nbsp;and training in how to use that. &nbsp;The site design was to be quite simple and make the logo prominent.</div><div><br /></div><div>The end result is here:</div><div><a href="http://www.redchipconstructions.com.au/">http://www.redchipconstructions.com.au</a></div>Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-62631799926004974942011-12-14T17:42:00.000+10:002013-01-13T17:43:56.833+10:00Side Project: Online Book & Blog for DoctorI worked on a little side project in 2010 for a Doctor who had written a book. He wanted to get the book available free to read online. He also wanted a blog to discuss topics with readers of the book. <br /><br /><a name='more'></a>Some other requirements were for the ongoing hosting/maintenance to be low/no cost and easy to manage. &nbsp;Also a lot of in-person and phone training was provided, as well as documented user guides.<br /><br />The solution included getting the book uploaded on <a href="http://www.scribd.com/" target="_blank">Scribd</a> and <a href="http://books.google.com/" target="_blank">Google Books</a> to ensure maximum exposure and different options for readers.<br /><br />The resulting website is here:&nbsp;<a href="http://www.themazewithin.com/">http://www.themazewithin.com</a>Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0tag:blogger.com,1999:blog-7170613974457474822.post-2263395388981879352011-12-13T20:49:00.000+10:002013-01-13T15:48:41.410+10:00Making Custom Built Applications “Saleable”<br />One of the requirements for my team is to ensure any software we build for our own organisation could be packaged up and sold to another organisation with instructions on how to customize and deploy it. &nbsp;This came about through various requests for our software that had been shown at conferences and demonstrations. &nbsp;Back when the original requests came in (2007-2008) we would have had to do a significant amount of work to be able to “sell” the applications. &nbsp;One of the requests was from a Healthcare software vendor, wanting to purchase an application we wrote to address inadequacies in their system! &nbsp;Most requests however come from other Healthcare organisations (including Government) and they have just seen what we have produced and think it will also work in their environment. &nbsp;This requirement now exists by default for most new applications unless there is a specific reason we would not want to sell a particular application.<br /><a name='more'></a><br /><span class="Apple-style-span" style="font-family: inherit;"><br /></span><span class="Apple-style-span" style="font-family: inherit;">I am not sure if this kind of requirement is common in other industries. &nbsp;I am assuming not because in a lot of industries that are developing custom software, each company is trying to get a competitive edge by building software that makes them more efficient and gives them an advantage over their rivals. &nbsp;In the not-for-profit Healthcare space we share as many ideas as possible with other Healthcare organisations and Government Healthcare agencies to help reduce rework and produce a better outcome for patients.</span><br /><span class="Apple-style-span" style="font-family: inherit;"><br /></span><span class="Apple-style-span" style="font-family: inherit;">Our team primarily builds web applications. &nbsp;Back in 2007 when this requirement was introduced the best solution seemed to be to use the <a href="http://en.wikipedia.org/wiki/Provider_model" target="_blank">ASP.NET Provider Model</a>. &nbsp;We successfully used that in applications up until now and it works nicely. &nbsp;Before the introduction of IOC into our team, it gave us nice separation of concerns for our “integration” code. &nbsp;Basically any functionality that was not core to the system would be extracted out into a “custom provider”. &nbsp;So for example, “SearchForPatient” might be a method on one custom provider. &nbsp;If another company were to purchase the software and deploy it, they could create their own implementation of the custom provider (which is just an abstract class) and implement that patient search method to search their own repository of patient data. &nbsp;They could then drop the DLL into the BIN folder and update the web.config to tell the application to use their provider instead of ours. &nbsp;This was a good solution for its time, but can cause issues with nasty configuration as there are no conventions!</span><br /><span class="Apple-style-span" style="font-family: inherit;"><br /></span><span class="Apple-style-span" style="font-family: inherit;">With such great IOC containers available (we are currently using <a href="http://code.google.com/p/autofac/" target="_blank">AutoFac</a> for ASP.NET MVC applications); I have started to investigate if there is a “better way” to achieve this “saleability” than using the Provider Model. &nbsp;If we use IOC properly, we might be “double hopping” in order to use a provider – because the IOC container needs to register the custom provider, which then uses the provider’s config to set itself up and get an implementation instance. &nbsp;I have not done any performance testing but this seems like overkill and if nothing else it is a bit confusing for new developers. &nbsp;In another project I have seen, there is a mix of IOC and providers due to commonly used providers such as the Membership and Role Providers. &nbsp;So that is a good example where the project will generally have an interface to wrap the Membership Provider methods it needs, then the implementation at run time will pick up a class that instantiates the Membership Provider via configuration (as normal) and passes through the calls to that Membership Provider. &nbsp;It makes sense to do that because the <a href="http://msdn.microsoft.com/en-us/library/system.web.security.sqlmembershipprovider.aspx" target="_blank">OOB Membership Providers</a> have a lot of logic within them that you don’t want to be replicating. &nbsp;However in my case, we are hand-rolling Custom Providers which would then get wrapped by an interface and calling implementation class for IOC purposes – so it seems wrong.</span><br /><span class="Apple-style-span" style="font-family: inherit;"><br /></span><span class="Apple-style-span" style="font-family: inherit;">One option to replace the Provider Model would be to use the <a href="http://code.google.com/p/autofac/wiki/XmlConfiguration" target="_blank">configuration "mode" of an IOC container</a>. &nbsp;This could be slightly cleaner than the Provider Model because you could programmatically hook up the dependencies by default, but just allow configuration as an optional “override”, leaving our in-house code base nice and clean but anyone else who uses it with a bit of a configuration mess.</span><br /><span class="Apple-style-span" style="font-family: inherit;"><br /></span><span class="Apple-style-span" style="font-family: inherit;">Another option might be MEF. &nbsp;The <a href="http://mef.codeplex.com/" target="_blank">next version of MEF</a> (still in preview) is a viable IOC container and it has some great conventions which should allow someone to “drop in” an implementation over the top of the default one and that could pick it up with absolutely no configuration!</span><br /><span class="Apple-style-span" style="font-family: inherit;"><br /></span><span class="Apple-style-span" style="font-family: inherit;">For now since we have decided to go with AutoFac in MVC project my aim is to set it up that way to do away with any Provider Model implementations in those new MVC projects.</span><br /><span class="Apple-style-span" style="font-family: inherit;"><br /></span><span class="Apple-style-span" style="font-family: inherit;">I jumped on the IOC bandwagon later than I would have liked to (and am never looking back) so I would be interested to hear some comments from some IOC/MEF “gurus” on whether I am heading down the right track or if there is something I have not thought of! &nbsp;Also if you are facing a similar issue and want to discuss leave a comment.</span><br /><div><br /></div><br />Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com1tag:blogger.com,1999:blog-7170613974457474822.post-20064960382385139872011-12-13T10:28:00.000+10:002013-01-15T00:15:13.284+10:00Welcome to Nootn.com.au! What is the purpose of this blog?I read a lot of blogs.&nbsp; Mostly technology related to do with programming languages and frameworks as they help me learn about the latest and greatest technologies I can use to help me build the best software possible.&nbsp; I also read some blogs about management and agile development methodologies, as that is another part of my role.&nbsp; The other main category of blogs I read is Health Industry related news.&nbsp; That gives me a good knowledge of what’s going on in the Industry so I can try and be ahead of the game.<br /><a name='more'></a><br />I decided to start my own blog for the following reasons:<br /><ol><li>Knowledge base – so I can record my thoughts/decisions to refer to them at a future date </li><li>To get feedback from other people about my thoughts/decisions </li><li>To try and provide a useful news source for other people in a similar position to me who are looking for a Health Industry related Software Development blog</li><li>To post information about projects I am working on or have worked on</li></ol>I have no technology bias although I do tend to use Microsoft products for a large amount of the programming work I do.&nbsp; I find the Microsoft toolsets and frameworks very conducive to a productive programming team.<br />I am not sure how often I will blog or what content will come out in the blog, I have no set plan, I will just see where it takes me.&nbsp; If I end up getting nothing out of it, I will cease, so please provide any comments or feedback if I seem to be slowing down and you would like to see more.<br /><br />Andrew Newtonhttps://plus.google.com/100508578871900935503noreply@blogger.com0