About Me

Training

Nothin But .Net Developer Bootcamp

Navigation

Search

Categories

On this page

Speaking at the new Edmonton .Net User Group
Something to Ponder
Questions about source code
ReSharper 2.0 Beta Has Officially Begun
Answers To Some Good Questions
Suggestions for presentation material
Automating Your Builds With NAnt - Part 5
DNRTv Episode on Model View Presenter Just Published
Automating Your Builds With NAnt - Part 4
Automating Your Builds With NAnt - Part 3
Automating Your Builds With NAnt - Part 2
Automating Your Builds With NAnt - Part 1

Archive

Blogroll

 Agile Developer Venkat's Blog
 Ayende @ Blog
 B#
 Barry Gervin's Software Architecture Perspectives
 Boy Meets World
 Brad Abrams
 Canadian Developers
 Christopher Steen
 Claritude Software News
 Clemens Vasters: Enterprise Development and Alien Abductions
 Coding Horror
 Coding in an Igloo
 Dare Obasanjo aka Carnage4Life
 Darrell Norton's Blog [MVP]
 David Hayden [MVP C#]
 Don Box's Spoutlet
 Eric Gunnerson's C# Compendium
 EZWeb guy: Jeffrey Palermo [C# MVP]
 Fear and Loathing
 Generalities & Details: Adventures in the High-tech Underbelly
 Greg Young [MVP]
 Greg's Cool [Insert Clever Name] of the Day
 IanG on Tap
 Ingo Rammer's Weblog
 ISerializable - Roy Osherove's Blog
 James Kovacs' Weblog
 Jason Haley
 Jean-Luc David
 Jeremy D. Miller -- The Shade Tree Developer
 JetBrains .NET Tools Blog
 Jimmy Nilsson's weblog
 John Bristowe's Weblog
 John Papa [MVP C#]
 Jon Skeet's Coding Blog
 JonGalloway.ToString()
 Jump the Fence or Walk Around
 Lambda the Ultimate - Programming Languages Weblog
 Larkware News
 Lutz Roeder
 Marquee de Sells: Chris's insight outlet
 Martin Fowler's Bliki
 Mike Nichols - SonOfNun Technology
 MSDN Magazine - .NET Matters
 MSDN Magazine - All Articles
 OdeToCode Blogs
 Onion Blog
 Planet TW
 Raymond Lewallen [MVP]
 Rockford Lhotka
 RodMan's Corner
 Roger Johansson's blog
 Sahil Malik - blah.winsmarts.com
 Sam Gentile's Blog
 Scott Bellware [MVP]
 Scott Hanselman's Computer Zen
 ScottGu's Blog
 secretGeek
 Service Station, by Aaron Skonnard
 Signum sine tinnitu--by Guy Kawasaki
 Stephen Toub
 Steve Eichert's Blog
 Steven Rockarts
 The Blog Ride
 The Coding Hillbilly
 The Daily WTF
 TheServerSide.net: News
 Tim Gifford
 Vance Morrison's Weblog
 you've been HAACKED

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 397
This Year: 122
This Month: 0
This Week: 0
Comments: 1033

 Wednesday, April 26, 2006
Wednesday, April 26, 2006 2:56:44 PM (Mountain Standard Time, UTC-07:00) ( Presentations )

Sorry for the late notice, but I thought I should quickly mention (for anyone who lives in/near Edmonton) that I have been graciously invited to come at speak at the new Edmonton .Net Users Group.

I am honored that I was asked and am looking forward to what should be an interesting evening. Hopefully people will not be too distracted by the big hockey game!! The meeting starts tomorrow (April 27th) at 5:30 pm in the Milner (downtown) public library’s Centennial Room.

See ya there.

Comments [5] | | # 
Wednesday, April 26, 2006 12:57:31 PM (Mountain Standard Time, UTC-07:00) ( Agile )

In case you haven't already read it. Scott Bellware wrote a very thought provoking article (which I wholeheartedly agree with) on the state of software development. You can read it here.
Comments [0] | | # 
 Tuesday, April 25, 2006
Tuesday, April 25, 2006 6:27:13 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | C# )
I have had numerous people contact me asking to deliver the source code that I used for the DNRTv episodes. Obviously, I am happy to release the source code as my main goal is to share information. To that end, I am going to suggest an alternative to just “releasing the source”. I am proposing a series of blogs and or screencasts that will detail building the entire application used on the DNRTv segment from UI to data access. This would allow for full detailed coverage of what is going on under the hood, and could provide for some meaningful discussions etc. This is just an idea that I am throwing around. If the majority would just prefer the source to be released as is, then that is the route I will take. I can only release the source for the 3rd episode of DNRTv as the material from episodes 1 & 2 are part of an upcoming (July hopefully) MSDN article. At which time the source code will be released. If people opt to go with the detail route, we will start with the buildfile and end with the data access layer. That’s right, we’ll use TDD, Mocks, etc to build the application from front to back as opposed to back to front!!
Comments [14] | | # 
Tuesday, April 25, 2006 8:02:42 AM (Mountain Standard Time, UTC-07:00) ( Tools | VS2005 )

For all of you who are not too keen on installing EAP software, the wait is finally over. Jetbrains has now announced the official beta for ReSharper 2.0. In case you are not aware of ReSharper, it is an add-in that dramatically improves the usability of Visual Studio, from a coder’s perspective. Basically, once you are used to developing with ReSharper you will find yourself hard pressed to go back to plain old VS2005. If you have not yet given ReSharper a try, I encourage you to download a copy of the beta and give it a whirl!! There is also an incentive to purchase a copy of 1.5 now, and get a free upgrade to 2.0 when it becomes officially available in May.

 

Rs20beta1._bg

Comments [0] | | # 
 Wednesday, April 19, 2006
Wednesday, April 19, 2006 3:25:23 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | C# | Patterns )

After my last presentation on DNRTv MauricioC asked some good questions that I thought I should post some answers for. I am reposting the questions from the comments that he made to give you a context for the answers:

Q: By the way, I also have an architecture question. When implementing the Service Layer pattern (as in Martin Fowler's Patterns of Enterprise Application Architecture), where would you put persistence code? The example on the book puts methods for filling the Domain Objects in themselves, but I am a little uncomfortable in introducing a dependency for the Data Access Layer in my Domain Layer (even while using Inversion of Control). Would you retrieve/persist data in the Service Layer itself, or the dependency is manageable and I am being paranoid?

A: As with many patterns there are a multitude of ways that the pattern can be implemented. As Martin points out, the two most common approaches for the service layers are the “Domain Facade” and “Operation Script”. I tend to lean toward the domain facade approach as it keeps my logic inside of the domain objects as opposed to dispersed through multiple methods in the service layer. As far as persistence is concerned the approach that Mauricio is talking about when having domain objects responsible for persisting themselves is the Active Record approach. As he says, this places a dependency on the data access layer in the domain model. I prefer having a completely isolated domain model, one that knows nothing about the service layer, data access etc. This allows you to drive out the functionality of the domain model in isolation from anything else. In this scenario, the service layer would be responsible for talking to some sort of MapperRegistry to retrieve mappers that know how to persist objects that need to go back to the database. Again, with a domain facade the service layer code is kept as thin as possible. Having discrete mappers that know how to persist objects/families of objects, removes this responsibility from both the domain model and the service layer and puts it where it should be, in a mapping layer. Mappers can be developed test first to ensure that if a mapper is given a particular object that it can read/delete/insert that object. So the long and short of it is :

The Service Layer coordinates the persistence, but it doesn't perform the persistence.

Again, the active record pattern is still a viable alternative if you are working with a simpler object model, and you are comfortable with domain objects being responsible for persisting themselves.


Q:Another very related question: Would you use test-driven development to create the service layer (I mean, it is a very thin wrapper that should not need inversion of control, as it's common for such facades)? The same question applies for the view in the MVP pattern: If you had used TDD in DNRtv, what parts of the view would have been tested?

A: The short answer is yes. Assume you were asked to build out a new method that needs to exist on a service layer class. This method will be called whenever a new Customer is to be added to the system. Here’s the catch, there is currently no mapper for a Customer object. And yet you still want to carry on developing the method without that in place. You can utilize TDD to drive out this scenario, even without the actual concrete mapper in place. If everything was already in place, then the test serves as a sanity check that the service layer class is talking and interacting with its dependencies as it should. An example of such a test would look like this.

 



using System;
using NUnit.Framework;
using Rhino.Mocks;

namespace DataLayer.DataAccess.Test
{
    [TestFixture]
    public class CustomerTaskTest
    {
        MockRepository mockery;

        [SetUp]
        public void Setup()
        {
            mockery = new MockRepository();
        }

        [TearDown]
        public void TearDown()
        {
            mockery.VerifyAll();
        }

        [Test]
        public void ShouldBeAbleToCreateNewValidCustomer()
        {
            ICustomerMapper customerMapper = mockery.CreateMock<ICustomerMapper>();
            CustomerDTO dto = new CustomerDTO("JP","Boodhoo");

            ICustomerTask task = new CustomerTask(customerMapper);

            customerMapper.Insert(null);

            LastCall.On(customerMapper).Constraints(
                Is.NotNull() &
                Is.TypeOf(typeof(Customer)) &
                Property.Value("FirstName","JP") &
                Property.Value("LastName","Boodhoo"));

            mockery.ReplayAll();

            task.CreateNewCustomer(dto);        

       }
    

    
    }
}

Notice that I am taking advantage of a new mocking framework that I have come to love (RhinoMock .Net). I am going to write up another post about working with RhinoMock, for those of you who have used NMock2 (also a great framework), the immediate distinction between the two is that I can actually set expectations by actually invoking the methods on a mock interface. Again, I will save the details of using RhinoMock for another post. This test was written test first without any existing code in place, but the intent of what the concrete service layer class should do is evident. After calling the CreateNewCustomer method we know that the service layer class is going to invoke the “Insert” method on a ICustomerMapper implementation, and the Customer object that gets passed to the insert method will have had its firstname and lastname properties set. That is is. Thin service layer. We are not testing that the service layer can actually map the Customer to the database, we are testing that given a CustomerDTO, the service layer class can:

  • Unwrap the DTO and create the necessary Customer domain object
  • Invoke the Insert method on a ICustomerMapper implementation

A test around a concrete ICustomerMapper implementation would actually verify whether a customer could be mapped to the database. If you want to see the code for the CustomerTask class, here it is:

 

public class CustomerTask : ICustomerTask
{
        private ICustomerMapper customerMapper;

        public CustomerTask(ICustomerMapper customerMapper)
        {
            this.customerMapper = customerMapper;
        }

        public void CreateNewCustomer(CustomerDTO dto)
        {
            customerMapper.Insert(new Customer(dto.FirstName,dto.LastName));
        }
}
 
In this scenario, this results in an extremely "thin" service layer class. As far as testing the view in an MVP triad, now we are getting into the functional testing layer where you would want to use some sort of automated UI runner. For windows NUnitForms is a great free one, and for the web Ruby & Watir are a great combination. Again, when testing at the actual UI layer, you are really trying to test the thin layer that can’t easily be accessed by the presenter (unless you tie presenters specifically to one particular UI framework).
Comments [6] | | # 
 Tuesday, April 18, 2006
Tuesday, April 18, 2006 11:29:50 AM (Mountain Standard Time, UTC-07:00) ( Presentations )

I believe that for presentations to be truly successful they need to focus on material, concepts, and strategies that are meaningful and useful to developers in the real world. With that being said, I am looking for help in choosing material that I should consider presenting at the upcoming Calgary Code Camp. If you are not familiar with the Code Camp, here is a summary of what a code camp is from the Code Camp Manifesto:

 -------------------------------------------------------------------------------------------------

  1. By and For the Developer Community

Code Camps are about the developer community at large. They are meant to be a place for developers to come and learn from their peers. Topics are always based on community interest and never determined by anyone other than the community.

 

  1. Always Free

Code Camps are always free for attendees.

 

  1. Community Developed Material

The success of the Code Camps is that they are based on community content. All content that is delivered is original. All presentation content must be provided completely (including code) without any restriction. If you have content you don’t want to share or provide to attendees then the Code Camp is not the place for you.

 

  1. No Fluff – only Code

Code Camps are about showing the code. Refer to rule #1 if you have any questions on this.

 

  1. Community Ownership

The most important element of the Code Camp is always the developer community. All are welcome to attend and speak and do so without expectation of payment or any other compensation other than their participation in the community.

 

  1. Never occur during work hours

We need to understand that many times people can’t leave work for a day or two to attend training or even seminars. The beauty of the Code Camp is that they always occur on weekends.

 

---------------------------------------------------------------------------------------------------

As you can see, the goals for a code camp are pretty straightforward. I think it is a great idea. To maximize the potential for the day there are a lot of topics that I have thought about speaking on, but I thought I would throw this post out there in the hopes that one (or more) of my readers would propose some suggestions for material that they would like to see if they were able to attend. Obviously, if you have seen some of my recent DNRTv episodes (MVP aside), I am a big proponent of agile, and I like to demonstrate the practical applicability of TDD. And I would be welcome to entertain ideas for things people would like to see done in the context of driving out the solution using TDD. Some of my thoughts for presentation material are as follows:

 

Writing a Basic ORM Layer

Patterns for the Data Access Layer

Validation Strategies

Isolating the Domain Model

Simplifying Logic in the User Interface

Pragmatic AJAX

 

This is just a quick cursory list. Again though, since this is supposed to be driven by the developer community I would much rather present on something that a majority of people would like to see, as opposed to something that may only be interesting to me. I appreciate any feedback anyone could provide.



Thanks

Comments [5] | | # 
 Monday, April 17, 2006
Monday, April 17, 2006 4:09:57 PM (Mountain Standard Time, UTC-07:00) ( Tools )

I left off talking about building and compiling the NUnit tests for the application. Of course, what good are tests if you can’t run them and see results! Time to shift our attention toward running the tests in an automated fashion so that we can get feedback on the health of the application. All of the tests that are currently in the application were written with the aid of the great NUnit testing framework. Typically I utilize the NAnt exec task to shell out to the NUnit console application to run all of the tests defined in an assembly. I prefer this to the actual nunit task and its variants as my build file is not affected in any way when I upgrade to a newer version of NUnit. Last time we left off with 2 compiled assemblies in the build directory. One assembly for the code to be tested, and one assembly for the tests themselves.

BuildDirectoryPreTest It’s time to add a new target to the build file that will allow for execution of the tests:

<target name="test" depends=”test.compile”>
</target>

Notice that by again taking advantage of the “depends” attribute, we can ensure that the tests have been compiled prior to test execution.The first thing you need to see is if there are any objects that you are going to be testing that require a dependency on a .config file. If they do then you first need to copy the web/app.config into a file that NUnit can work with. It is always the same file name format “[ProjectName].Test.[OutputExtension].Config”. In our scenario, because the project name is DotNetRocks, the config file would get copied to the file :

DotNetRocks.Test.dll.config

To keep everything in one place (highly recommended) I am going to copy the config file (using the new name) to the build directory. To accomplish this I can make use of the copy task.

<target name="test" depends=”test.compile”>
    <copy file="config\Web.Config" tofile="build\${nant.project.name}.Test.dll.config" />

</target>

Of course, you would change the location as necessary to pull the Web.Config file from wherever it may reside in your directory structure (typically with the web/win project itself). With the config file taken care of, I now need to copy to the build directory any libraries that will need to be in the build directory for the tests to work. In this particular scenario I need to copy the NUnit and NMock2 libraries into the build directory. Once again, I can take advantage of the copy task to accomplish this:

<target name="test" depends=”test.compile”>
       <copy file="config\Web.Config" tofile="build\${nant.project.name}.Test.dll.config" />
        <copy todir="build" flatten="true">
            <fileset basedir="tools">
                <include name="**\NMock2.dll" />
            </fileset>
        </copy>
         <copy todir="build" flatten="true">
            <fileset basedir="tools\nunit\bin">
                <include name="*.dll" />
            </fileset>
        </copy>
              
    </target>

As you can see, because the tests make use of both the NUnit and NMock2 frameworks, I need to copy all of the relevant dll’s from those frameworks into the build directory before the tests can run. NUnit is an interesting one, because sometimes you can get away (by sheer fluke) with this step and NAnt will fallback to using the NUnit version that is installed in the GAC (if you installed NUnit on your machine). This is problematic though. If you upgrade the version of NUnit in your tools directory and build your tests against that version of NUnit, you will only be able to run the tests using the GAC version if it matches the one in your tool directory. If the versions are different, you will get an error when you try to run your test. Again, getting back to the principle of  “keeping everything you need to run the project in one place” it is best to avoid reliance on the GAC for NUnit and the like. This is why all of the necessary dlls from both frameworks are being copied into build directory. If I were to stop there, the build directory would look like this after running the test target:

BuildDirectoryPreTest2

As you can see all of the files we actually are responsible for generating/maintaining are at the top of the directory (notice the config file with the correct NUnit naming convention), all of the other 22 dlls (that list could be streamlined by changing the filter for the fileset) are purely there for running the tests.

With the supporting files all in place it is time to run the tests. To accomplish this, it is time to use a new task. The exec task. Again, I am not going to go into all of the details, attributes etc for the exec task, as the NAnt docs do a good job of that. I’m going to focus on using it to run NUnit. I’ll need to update my test target:

<target name="test" depends="test.compile">
  <copy file="config\Web.Config" tofile="build\${nant.project.name}.Test.dll.config" />       
       
        <copy todir="build" flatten="true">
            <fileset basedir="tools">
                <include name="**\NMock2.dll" />
            </fileset>
        </copy>
       
        <copy todir="build" flatten="true">
            <fileset basedir="tools\nunit\bin">
                <include name="*.dll" />
            </fileset>
        </copy>
                                      
        <exec basedir="tools\nunit\bin"
              useruntimeengine="true"
              workingdir="build"
              program="nunit-console.exe"
              commandline="${nant.project.name}.Test.dll /xml=${nant.project.name}.Test-Result.xml" />
           
       
    </target>

Pay attention to 2 of the key attributes : basedir and workingdir. basedir is the directory that the program I want to execute is in. workingdir is the directory in which the program will execute (hence the need to copy all required dlls,config files etc to the build directory). The program attribute is self explanatory, and finally the commandline attribute is the argument string to invoke the program with. Notice I am telling nunit to execute against the test library I have place in the build directory (DotNetRocks.Test.dll), and I want the results of the tests to be placed in a file named DotNetRocks.Test-Result.xml (this file will be placed in the build directory). If I run my test target now I will get the high level results output to the console, consoleoutputas well as a xml file containing detailed tests results placed in the build directorytestresults. As a quick heads up for things to come, I will talk about how you can integrate the results that are spit out by the NUnit console into a continuous build engine (CC.Net), for analyzation and integration of the results into the build process.

 

Hopefully this will get you started on the way to integrating automated tests into your build infrastructure. Next up, let’s bring the DB into the picture!






TODO
Comments [0] | | # 
 Thursday, April 13, 2006
Thursday, April 13, 2006 11:56:50 AM (Mountain Standard Time, UTC-07:00) ( ScreenCasts )

A new episode that I recorded with Carl Franklin on DNRTv is now available for viewing. The show is a breakdown of implementing the Model View Presenter design pattern. I chose, based on feedback, to focus solely on the use of the pattern. This should help people who were feeling cluttered by the test-driven-development!! Of course, when I am developing applications, I always pragmatically apply test driven development. So to answer your question, yes I would have used TDD to drive out the functionality of the view and presenter as opposed to the ad-hoc coding that I did on the current show.

One of my goals for this blog, is to be an outlet to show the practical applicability of TDD, design patterns etc, in the building and architecting of enterprise applications. I also have screen recording software available on my machine, so if there are topics you would like me to VBLOG about, as opposed to hogging all the DNRTv slots, then please let me know and I will do my best to record a quick screencast on the topic.

I would finally like to thank all of the people who have taken the time to provide feedback both positive and negative. It is greatly appreciated.

Comments [18] | | # 
 Tuesday, April 11, 2006
Tuesday, April 11, 2006 3:15:45 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | C# | Tools )

In the last post I talked about compiling the main supporting assemblies for the web/win project. Let’s shift focus now to talk about building the associated unit tests for the application. The solution I was working with SolutionStructureactually had a 1–1 (almost) correspondence of Test projects per deployable projects. In my opinion, this structure is a lot better than placing the tests in the same project that you are testing as it makes separating the files from test/deployment builds a lot simpler, as you don’t need to worry about naming your files in a special way to exclude them from the build process. I have already successfully compiled each of the assemblies that needs to be tested, using NAnt I compiled all of the source from the 8 projects into a single assembly.

Before I can run my tests (in an automated fashion from the command line), they need to be compiled. It stands to reason that the NAnt xml required to accomplish this task is very similar to compiling the non-test projects:

<target name="test.compile">
        <csc target="library" output="build\${nant.project.name}.Test.dll" debug="${debug}">
            <sources>
                <include name="src\test\**\*.cs" />
                <exclude name="src\test\**\AssemblyInfo.cs" />
            </sources>                                                                            
                                                             </csc>
                                                     </target>

Everything looks good, right? I should be able to switch to the command line and run the “build test.compile” command. If I do that right now I will run into a few problems. I won’t even show you the screenshot for what the errors look like, as it will take up too much space. The long and short of it is that I cannot compile the test project without preserving references that are essential to allow the dll to be built. Wait, why was this not an issue for the last time I compiled? This was because the only things the other dll depended on were System assemblies that are automatically resolved by NAnt. The fact that all of the code from the 8 projects was being compiled into a single assembly eliminated the need to duplicate project level references. Unfortunately, as picture 2 shows, most (if not all) of the test projects Referencesneed to have a reference to the actual projects that they are testing as well as 2 third party utilities (NMock and NUnit).

Of course, I took care to ensure that when I created these references in Visual Studio that I pointed to the correct location of the tools within my tools folder (for NUnit and NMock2 that is). As far as the project references, all I had to do was add a standard project reference. Unfortunately, when I am in NAnt it knows nothing about these things. I have to set it up manually. Let’s make a small change to the test.compile target to compensate for this:

<target name="test.compile" depends=”compile”>
        <csc target="library" output="build\${nant.project.name}.Test.dll" debug="${debug}">
            <sources>
                <include name="src\test\**\*.cs" />
                <exclude name="src\test\**\AssemblyInfo.cs" />
            </sources>                                                                            
        </csc>
 </target>

Remember, the “depends” attribute for a target ensures that any targets listed for the value of that attribute have to run before this target can run. I am ensuring that the code to be tested has been compiled before I can compile the tests. Of course, I am still going to get compilation errors if I try to compile, as I have still not taken care of the references needed to build the test library. I’ll take care of NUnit and NMock2 first by making use of the references element:

<target name="test.compile" depends=”compile”>
        <csc target="library" output="build\${nant.project.name}.Test.dll" debug="${debug}">
            <sources>
                <include name="src\test\**\*.cs" />
                <exclude name="src\test\**\AssemblyInfo.cs" />
            </sources>

            <references>
                <include name="tools\nunit\bin\nunit.framework.dll" />
                <include name="tools\nmock\NMock2.dll" />                               
            </references>
                                                                        
        </csc>
 </target>

 

The references element is used by the csc task, to tell the compiler where to look for references required to build the project. As mentioned before, I don’t need to worry about framework libraries as NAnt resolves those for me. Again, note how referencing “references” becomes simpler when everything you need is located within your checkout directory!! Ok, I’m one step closer, but I still cantCompileError compile as it still cannot see classes that live in the assembly that should be being tested. As you have probably already guessed, I can fix this quickly by just adding another reference. But wait, what do I reference? Now you will see the important of having the “build” staging area, if you remember the compile target :

<target name="compile"
            depends="init"
            description="compiles the application">
        <csc target="library" output="build\${nant.project.name}.dll" debug="${debug}">
          <sources>
            <include name="src\app\**\*.cs" />
            <exclude name="src\app\DotNetRocks.Web.UI\*.*" />
            <exclude name="src\app\**\AssemblyInfo.cs" />                                
         </sources>                        
        </csc>

</target>

I already know where the dll that I need to reference is going to get placed, so I can just add a reference to it!!:

<target name="test.compile" depends="compile">
        <csc target="library" output="build\${nant.project.name}.Test.dll" debug="${debug}">
            <sources>
                <include name="src\test\**\*.cs" />
                <exclude name="src\test\**\AssemblyInfo.cs" />
            </sources>           
            <references>
                <include name="build\${nant.project.name}.dll" />
                <include name="tools\nunit\bin\nunit.framework.dll" />
                <include name="tools\nmock\NMock2.dll" />                               
            </references>
        </csc>
    </target>

With that change in place, I can now run the test.compile target, which will result in a new dll being placed in the build directory!! Next up, I’ll talk about running the tests in an automated setup, that will prepare us for when we start talking about CC.Net integration!!

TestCompile

TODO
Comments [3] | | # 
 Friday, April 07, 2006
Friday, April 07, 2006 1:03:58 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | C# | Tools )

Ok, last time we left off being able to clean/create a staging area for the build. Let’s now work on actually compiling the projects in the solution. If you take a quick look at the solution structure SolutionStructure you will notice that there are 16 projects. More than half of these projects are test projects, and one of them is a web project. To be more specific, I am using the standard VS2005 web project model to organize my web project. Some of you may not be aware but there is another model called the Web Application Project model, that basically looks and behaves very similar to the way web projects worked pre VS2005. More on that another day!! Today I will focus on just building the supporting assemblies for the web project. Right now, I am talking about a build for test, not for deployment. These are 2 quite different animals. When I am doing a build for test I can choose to take a very simple route and just compile all of the code from the 8 supporting projects into a single dll, as opposed to compiling them the way studio does. This also keeps the build file a lot simpler. More often than not, as developers we utilize projects as a way to logically organize the application. Whether or not each of the individual projects actually resolves to one deployable unit is a choice that you have to make as a project team. Personally, once you have an automated deployment scenario in place, it really does not matter. As deploying becomes (almost) as simple as running a NAnt target.

Let’s get back to actually building the 8 projects we are interested in. It stands to reason that some of the projects in the solution have dependencies on other projects in the solution ProjectReferences. Obviously these projects will not be able to build properly unless those references are maintained and obligated within the build file. A better question to ask is how do you actually go about compiling the 8 projects using NAnt? If you have been taking a look at the NAnt NAnt Task Reference reference you will notice that one of the tasks in there is the csc  task. This is a dedicated task with the sole responsibility of compiling C# programs. It stands to reason that this would have to enter the mix somewhere!!

I am not even going to try and attempt to cover all of the attributes/flags that can be used in conjunction with the csc task. I believe an example will speak louder than words and get you going in the right direction. Let’s switch back to the build file and start working on adding in the compile task. In case you forgot what the build file currently looks like, here it is:

<?xml version="1.0"?>
<project name="DotNetRocks" default="all">

    <property name="debug" value="true" />

   <target name=”all”/>

   <target name="clean" description="remove all build products">
        <delete dir="build"  if="${directory::exists('build')}" />
    </target>

    <target name="init">
        <mkdir dir="build" />
    </target>

</project>

I’ll add the entire compile target and then discuss and dissect for the remainder of the post:

<?xml version="1.0"?>
<project name="DotNetRocks" default="all">

    <property name="debug" value="true" />

   <target name=”all”/>

   <target name="clean" description="remove all build products">
        <delete dir="build"  if="${directory::exists('build')}" />
    </target>

    <target name="init">
        <mkdir dir="build" />
    </target>

    <target name="compile"
            depends="init"
            description="compiles the application">
        <csc target="library" output="build\${nant.project.name}.dll" debug="${debug}">
            <sources>
                <include name="src\app\**\*.cs" />
                <exclude name="src\app\DotNetRocks.Web.UI\*.*" />
                <exclude name="src\app\**\AssemblyInfo.cs" />                               
            </sources>                       
        </csc>
    </target>

</project> 

First point of interest is the use of the new “depends” attribute in the compile target. This tells NAnt to ensure that the “init” target has been run before the compile target runs. If the init target has not already been executed in this NAnt session, then NAnt will ensure that the init target is run before it carries on processing the compile target. NAnt processes dependencies from left to right so you can have a target depend on multiple targets using comma-separated lists such as : depends = “clean,init”. If you have a dependency on a target that also has a dependency on init, NAnt will make sure that the init target is only executed once, as not to waste execution cycles. The rest of the target deals with the actual csc task itself.

First off, I tell NAnt that I am going to be compiling a “library” (dll) and that it should place the resulting dll in the build directory. What’s with the ${nant.project.name} syntax? This is the way you access properties in NAnt. We did not, however, define that particular property in our build file. This is because ${nant.project.name} is one of many predefined NAnt properties that we can make use of during the build process. The value of the ${nant.project.name} property will resolve to the name you give your project in the project element of the build file:

<project name="DotNetRocks" default="all">

So when this dll is compiled it will actually be compiled to : build\DotNetRocks.dll.

Finally I have to tell the csc task, what files (sources) to include in the compile process. The sources element is actually just a NAnt fileset. I can include/exclude files from the fileset. Notice how I am excluding everything in the Web.UI project? Why, this is because I am using the WSP model and a lot of the code for web projects, when using this model, is dynamically generated. In a future post, I will show one way to compile the Web.UI project. I am also excluding any AssemblyInfo.cs file from the list of sources. If I did not do this, the compiler would choke because there would be multiple classes of type AssemblyInfo attempting to be compiled into the assembly. MultipleAssemblyInfos When I usually compile multiple projects into a single assembly, I usually create a single AssemblyInfo file for that group of projects, and include that AssemblyInfo file into the compile process.

With that target completed, I can run the compile target from the command line and see the result placed into my build directory.BuildDirectoryWithNewAssembly 

Next up is testing the assembly!!

 





TODO
Comments [2] | | # 
 Wednesday, April 05, 2006
Wednesday, April 05, 2006 2:41:19 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | Tools )

In the previous post we covered off solution structure and physical directory structure. It’s time to move on to talk about the actual build process. What does it mean to build? A “build” means different things to different people. For me building consists of the following crucial steps:

  • Cleaning up the results of a previous (if any) build process.
  • Creating a build area (folder)
  • Rebuilding databases (optional)
  • Compiling all project/solution related files
  • Compiling all test related projects
  • Running unit tests

Of course there are other activities that can occur in a build process, but the ones listed above are key. Notice that the “Rebuilding databases” step is optional, as there are lots of applications that do not require the use of database engines. I’ll break the process down step by step, so you can follow along if you desire. Before we can begin putting the steps in motion we are going to make use of a tool that will allow us to automate this process. Having some form of an automated build process is the key to enhancing your productivity as a developer. Getting back to a point I keep stressing, “A Developer should be able to do a fresh checkout and be able to hit the ground running.”.  As a developer, I would much rather do a fresh checkout and run some command at the command prompt to assert that my world is set up ok. As opposed to:

  • Checking Out
  • Opening the Solution file
  • Waiting for studio to load up
  • Building the solution
  • etc,etc,etc

In order to automate your build process you can take advantage of NAnt. NAnt is the open source, more mature, equivalent to MSBuild. Let me say that I think it is great that MS has introduced an automated build tool into the mix, and I am sure that eventually I will be able to retire NAnt and utilize it. In its current implementation, I definitely feel that NAnt is more feature rich out of the box, and a little easier to work with.

Setting Up The Build File

A NAnt build file, just like an MSBuild file, is nothing more than an xmldocument that is interpreted and executed by the NAnt runtime. Most of my build files start with the following basic skeleton:

<?xml version="1.0"?>
<project name="DotNetRocks" default="all">

    <property name="debug" value="true" />

    <target name=”all”/>

</project>

That’s it. This is the start of your build file. All these couple of lines of XML are telling NAnt is that this build file represents the project named “DotNetRocks” and that there is a global property called “debug” that has its value set to true. Most important is the “default” attribute. This attribute tells NAnt that the default target to execute is the “all” target. What is a target? More on that later. Think of properties defined at the top of the build file as variables that can be accessed (using the ${propertyName} syntax) during the build process.

So far this build file does not do much of anything, let’s take care of the first item on the build to-do list.

Cleaning up the results of a previous (if any) build process

Now of course, there are currently no unwanted artifacts to clean up, as I have not even completed a successful build yet. Don’t worry about that. The first thing you need to decide is where you want all of your build artifacts to go. When I say build artifacts, I am talking about dll’s, exe’s etc that result from compiling your projects. The following screenshot shows how I will augment my directory structure to support the build process:

BuildDirectory

There is one important thing you should realize about the “build” directory. It is created by the build process and is a completely transient directory. It exists solely for facilitating the placement of files and artifacts related to building and testing the project. As a side note, this directory would also not be under source control. Which means you would have to make sure that it is “ignored” from checkins/commits. The main executable unit for NAnt files is the <target> element. You can think of <targets> as subroutines that can be invoked to perform a series of tasks. Let’s change our build file to clean/recreate the build directory:

<?xml version="1.0"?>
<project name="DotNetRocks" default="all">

    <property name="debug" value="true" />

    <target name=”all”/>   

   <target name="clean" description="remove all build products">
        <delete dir="build"  if="${directory::exists('build')}" />
    </target>

</project>

Notice that the target element has attributes such as “description” that can be used to provide descriptive information about the targets contained in the build file. What about the nested element? The <delete> element is one of many NAnt tasks that can be composed within targets to provide the functionality contained within a target. Here I am using a conditional to tell NAnt to delete the build directory if it already exists. Within a NAnt build file, unless explicitly stated, all directory references are relative to the location of the build file itself. Which means when I tell NAnt to delete the ‘build’ directory, it will attempt to delete a subfolder named build in the folder where the build file itself is cont