Showing posts with label readify. Show all posts
Showing posts with label readify. Show all posts

May 5, 2011

This is How Support Messages Should Be Done!

Taken verbatim from an internal Readify announcement:

Some weeks ago, a company in Redmond, California released a major update to their current generation of Windows called "SP1". That's ​a boring name for a product that essentially improves and cleans up windows, so we'll refer to this product as "Windex" from now on. Windex is a great thing. IT took the time to put it on our own computers and tried it out. Sure enough, all our windows are cleaner and just better. There have been no bad effects to using Windex as yet.

Emboldened, we set upon a course of putting Windex everywhere we could. We gave it to our friends. We gave it to our colleagues. Everyone loves Windex! This week, we've been busily applying Windex to all the Readify servers. It's been a very positive experience and all Readify's servers have taken to Windex without complaint. In fact, they love Windex!

All our servers for the most part however all rely on three very powerful master machines that are the unsung heroes of our network. These magnificent machines are the quiet achievers of the Cloud network - they manage, control and look after all the servers you know and love; as well as all the servers you don't know and love yet (be assured you'd love them if you knew them). We'll call these three servers the "Hosts" of the network. These three hosts don't yet have Windex. They've seen Windex be put onto all the servers they look after, and have been patiently waiting for someone to come and apply some Windex to them.

That time has come!

... but there's a catch. As a part of applying Windex to any machine, you need to close and reopen the windows on it. I'll call this process "Rebooting". The rest of the network can't do anything if the hosts that look after them are rebooting. So, while the network isn't doing anything, neither will any of our staff. As a result, putting Windex on the hosts during the week would be bad™.

So, starting from about 2am on Sunday morning, while everyone is either in bed or out partying and not caring; These quiet achievers of the Readify family will finally get their Windex. If all goes well, they will be back up and running (and much better and cleaner) by the time you start trying using the network on Sunday. If all doesn’t go well, it’s ok we can still email you and tell you it didn’t go well – and trust us: We’ll know about it before you do. We’ll have all day Sunday to fix any snafu that may happen and still have the whole network ready to run by Monday morning. You may need to consider not doing any work on Sunday.

Kudos to the fantastic Nathan Thomas for always keeping us in the loop as to what’s happening.  I love it!

What’s the best downtime message you’ve ever seen?

Sep 22, 2009

Missed TechEd Australia? Get the content anyway

Close on the heels of TechEd Australia, Readify have announced the latest Dev Days events for both Sydney and Melbourne.

When we last ran these we had multiple tracks which presented tough choices on what to see at times, so we’ve changed things around and will now run separate morning and afternoon tracks instead.  It means you can now get to everything, or just come for the half day session you are interested in and go to the beach for the other half of the day (or do some work if you must).

I'll be presenting the morning session in Sydney, covering Software Quality and Application Lifecycle Management split across two subjects:

  • Gathering Quality Requirements for Agile Development Teams, and an
  • Introduction to Visual Studio Team System 2010.

In the afternoon, Tatham Oddie (MVP) will be covering Building for the Web with .NET through three different presentations:

  • Building Fast, Standards Compliant ASP.NET Websites,
  • ASP.NET MVC: Building for the web, and an
  • Introduction to the ASP.NET Web Forms Model-View-Presenter framework.

To find out more or to book just point your browser to http://readify.net/training-and-events/rdn-dev-days/.  See you there!

Oct 20, 2008

Unit Testing WCF Services

I've seen a lot of people test WCF services using integration tests.  You know, where you create a small program as a test harness that creates a client for a web service, calls the service and checks what happened.  Similarly when you want to test your client side code is using the service properly then you have to have your client talking to something, so you need to have a test service running and that can be a pain at times, especially if the service is hosted somewhere in the cloud.

Testing a WCF Service

Testing WCF services themselves is actually quite straightforward.  Since a WCF service library is really just a normal class library it means that WCF services can can actually be called and tested using NUnit, MSTest or your favourite xUnit framework without needing a proper WCF client at all as I'll show you here:

Let's start by adding a WCF Service to a service library:

image

When we do, we get two new files added to our project - MyService.cs and IMyService.cs.

MyService.cs is just a simple skeleton as shown here:

namespace WcfServiceLibrary1
{
public class MyService : IMyService
{
public void DoWork()
{
}
}
}

The interface likewise is also very simple:

namespace WcfServiceLibrary1
{
[ServiceContract]
public interface IMyService
{
[OperationContract]
void DoWork();
}
}

Nothing to it.  So let's implement something simple so that we at least have something to test :-)  How about we change DoWork() to return an int with the current hour of the day and update the interface definition to match.  Something like this:

        public int DoWork()
{
return DateTime.Now.Hour;
}

Now, being good programmers, we want to make sure our incredibly complex method works as expected so let's write a test for it.  Remembering that the MyService class is just a normal class we don't actually need to do anything via WCF at all.  Just test it like so:

        [TestMethod()]
public void DoWorkTest()
{
MyService target = new MyService();
int expected = DateTime.Now.Hour;
Assert.AreEqual(expected, target.DoWork());
}

I know the example is a little too simplistic, but you should get the idea.


Testing a WCF Client


So now that we have a working service how do call it?  And how do we test our client?  Now when we add a WCF service reference in our client project Visual Studio will generate the code for a WCF service client - it's this service client that our application will use, so is there any value in testing the client generated by Visual Studio itself?  Probably not.  So the question then becomes: how do we test that the WCF service client is being used correctly by our application code.


Let's start an example by adding a service reference to our WCF Service we created above, similar to what's shown here.  This is what we'll use in our client application.


image


Visual Studio goes ahead and adds the reference to the solution and behind the scenes creates a MyServiceClient class that we can then call from our application as shown in the following code:

        public string CallMyServiceClient()
{
int result;
MyServiceClient client = new MyServiceClient();
result = client.DoWork();
return result.ToString();
}

Code like the above is something you will see in many places around the web, however we have just made life a lot harder for ourselves than we need to.  Can you see the problem?  If I want to test the CallMyServiceClient method I have to instantiate a WCF client and call it, which also means I also have to have a WCF service running and ensure all my WCF end points are configured correctly for the test environment.  It's OK when it's a simple like this, but in a large application with many services and people involved this sort of thing can get out of hand very quickly.


Further, if I wanted some way to see what happens to my code should the service throw an exception I'd have some difficulties so my error handling code (or lack thereof) will usually go largely untested.


Thankfully there are a few simple changes we can make to make this testability problem go away.


First, have a look at the declaration of the MyServiceClient and you'll see that Visual Studio has generated something like this:

    [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class MyServiceClient :
System.ServiceModel.ClientBase<WCFClientLibrary1.MyServiceReference.IMyService>
, WCFClientLibrary1.MyServiceReference.IMyService {

public MyServiceClient() {
}

The interesting thing to note here is that MyServiceClient is implementing the IMyService interface.  So if we wanted we could remove the concrete class reference and use the interface like so:

        public string CallMyServiceClient()
{
int result;
IMyService client = new MyServiceClient();
result = client.DoWork();
return result.ToString();
}

But this doesn't help much since we still have that instantiation of the MyServiceClient in our method to deal with.  We need to get that out of there.  To do that we'll use Dependency Injection - a technique where instead of the class creating the dependencies it needs, we pass into the class everything else that the class has a dependency on - in this case the MyServiceClient class.  Here's how we could do it:

    public class MyClass
{
private IMyService client;

public MyClass(IMyService wcfClient)
{
client = wcfClient;
}

public string CallMyServiceClient()
{
int result = client.DoWork();
return result.ToString();
}

So now when we create an instance of MyClass we pass in an instance of the MyServiceClient class so that MyClass doesn't have to create a reference to MyServiceClient.  We could do this either through our own application code higher up the call stack or through the use of an Inversion of Control container such as Unity, Castle Windsor or any of the other choices out there.


Now that we've introduced dependency injection we have also given ourselves a way to test MyClass without actually hitting the WCF service client at all.


What we need to do is to create a fake version of the MyServiceClient class that we can use as a substitute for the real WCF service client and pass that to MyClass instead.  We could, if we chose, create this fake class ourselves, but mocking frameworks exist to make our life easier in the regard and come with a bunch of extra features that let us do things such as setting return values when calls are made, without us having to write that ourselves.


Here's a test we might use with our client using the Rhino Mocks framework:

        [TestMethod()]
public void ClientTest()
{
IMyService mock = MockRepository.GenerateMock<IMyService>();
mock.Expect(t => t.DoWork()).Return(10);

MyClass classUnderTest = new MyClass(mock);

Assert.AreEqual("10", classUnderTest.CallMyServiceClient());
mock.VerifyAllExpectations();
}

Let's have a look at this test in a little more detail.  What are we doing here?



  1. We're creating a fake version of the IMyService class called "mock".
  2. We then tell the mock object to return the value 10 when its DoWork method is called.
  3. Next we create a MyClass instance and pass the fake class through to it in place of a real WCF service client.
  4. Then we call our classUnderTest and assert that the method returned the expected value
  5. And on the last line we also check that the DoWork() method was called on our mock object (i.e. we didn't just return from MyClass without calling the IMyService method)

This is quite useful as we now have a way to test our application code is making the appropriate calls to the WCF client without needing to actually spin up a full WCF client & service nor do we have to do any testing across the wire.  This example is also simple enough to extend so that when the DoWork() method is called we can throw a WCF exception instead to test how well our class handles failures.


I hope this helps you improve your testing with WCF in the future.  Good luck!

Oct 10, 2008

Handling Bad Task Estimations in a Sprint

Consider the following hypothetical situation I was talking about with Aaron a while back:

Fictional company ExWhyZed has 8 people in a Scrum team doing a 4 week sprint. The team is comprised of developers with some specific skills; basically 4 front end web developers who love their Silverlight UI's but suck at DDD and persistence, and 4 back end developers, who don't have much in the way of l33t web skillz.

Since they're doing Scrum they know they should deliver increments to the product in vertical slices, so they're all in the same team working on the same product backlog item, but coming at it from different ends of the equation.

During sprint planning the front end guys made estimates for tasks to delivering the UI, everyone worked together to estimate the front/back end interactions and the back end guys estimated their tasks for persistence and so forth.  The first few weeks of the sprint went OK but by week 3 the front end guys found that they've estimated some tasks poorly and are going to be late.  The back end developers also estimated poorly, but actually overestimated so they are all but done with their tasks by week 3.

If you were in the team what do you think you'd want the team to do? And why?

  • The back end guys should get more items from the product backlog and start working on them
  • The back end guys should just do more testing
  • The front end guys should give the back end guys some tasks to do
  • Front and back end guys should do pair programming
  • Back end guys should do some refactoring, catch up on blogs, do some reading, work on private projects, etc
  • The team should think about cancelling the sprint and start again
  • Something else?

And before you ask yes, this is genuinely hypothetical situation, but it is a fairly common one. I'm simply curious as to what you would do, and why.  Leave a comment with your thoughts.

Oct 7, 2008

A Quick Play With IBatis.NET

You may remember a few posts back that I was working with a team trying to use a pure stored procedure approach to access a database, and trying to do so using an OR/M. One of the commenters on the post mentioned iBATIS. Now I always thought iBATIS was a competitor to NHibernate, Linq2SQL, et al. but it's actually a different approach where instead of being a fully blown OR/M it just does simple data mapping of business objects to and from SQL statements and nothing more than that.

So I decided to have a bit of a play with it and I must say it looks pretty good. Here's a quick bit of sample code I knocked up to see how it works.

Assume I have the following sproc:

CREATE PROCEDURE InsertSaleHeader
@Tax money,
@TotalValue money,
@SaleNumber int output
AS
BEGIN
SET NOCOUNT ON;

INSERT INTO [dbo].[SaleHeader]
([Tax]
,[TotalValue]
,[ModifiedDate])
VALUES
(@Tax,@TotalValue,GETDATE())
SET @SaleNumber = scope_identity()

END

It's just a basic insert sproc that updates a modified date on insert and also returns a new identity value for the record we just added using an out parameter. This is the sort of thing that was a real pain to so with many of the full featured OR/M's.


I then wrote an integration test (p.s. please forgive my incorrect casing in places):

using IBatisNet.DataMapper;
using SalesDAL.ibatis;

namespace SalesIntegrationTests
{
[TestClass]
public class ibatisSaleRepositoryTests
{
[TestMethod]
public void CreateSaleAndGetSalesUsingIBatis()
{
ISqlMapper mapper = Mapper.Instance();
ISaleRepository repository = new ibatisSaleRepository(mapper);
ISale sale = new SalesTax.Sale();
sale.Add(new SalesTax.SaleLine(1, "imported box of chocolates", 10.00m, true));
bool result = repository.CreateSale(sale);
Assert.IsTrue(result);
}
}
}

This just creates an instance of a sale object and sends it to a sale repository class. The code for the ibatisSaleRepository is shown below.

namespace SalesDAL.ibatis
{
public class ibatisSaleRepository : ISaleRepository
{
private ISqlMapper mapper;

public ibatisSaleRepository(ISqlMapper mapper)
{
this.mapper = mapper;
}

public bool CreateSale(ISale sale)
{
mapper.Insert("InsertSaleHeader", sale);
LastSaleId = sale.SaleNumber;
return true;
}

public int LastSaleId
{
get;
private set;
}

As you can see the only actual work that happens is in the CreateSale() method where the IBatis Insert() method is called, passing in the object to be saved (note that I’m only saving the sale header here – we could extend this to save the sale lines easily enough).

And that’s it for the code. Nothing too complex at all. The rest of the work is done through the config files that IBatis loads during the Mapper.Instance() method call in the unit test. When it's initialised iBATIS loads up the SqlMap.config file and then processes it any other config files that are reference by it to create the mapping behaviours it needs to know.

The IBatis SqlMap.config file I used is shown here:

<?xml version="1.0" encoding="utf-8" ?>
<
sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<
settings>
<
setting useStatementNamespaces="false"/>
</
settings>
<
providers embedded="providers.config, SalesIntegrationTests" />
<
database>
<
provider name="sqlServer2.0"/>
<
dataSource name="SalesData" connectionString="Data Source=.;Initial Catalog=SalesDatabase;Integrated Security=True"/>
</
database>
<
sqlMaps>
<
sqlMap embedded="ibatis.SalesMap.xml, SalesDAL"/>
</
sqlMaps>
</
sqlMapConfig>

And finally the SalesMap.xml file is as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<
sqlMap namespace="SalesDAL" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<
alias>
<
typeAlias alias="SaleHeader" type="SalesInterfaces.ISale, SalesInterfaces" />
</
alias>
<
statements>
<
procedure id="InsertSaleHeader" parameterMap="InsertSaleHeader-Params">
dbo.InsertSaleHeader
</procedure>
</
statements>
<
parameterMaps>
<
parameterMap id="InsertSaleHeader-Params" class="SaleHeader">
<
parameter property="Tax" />
<
parameter property="TotalValue" />
<
parameter property="SaleNumber" direction="Output" column="SaleNumber" />
</
parameterMap>
</
parameterMaps>
</
sqlMap>


I won't go into all the details of the configuration, but as you can see it's not onerous in any way. In fact I found that overall iBATIS it’s a lot simpler to use than NHibernate for this type of operation and it's much easier and faster using it than doing the alternative and writing ADO.NET by hand.

Oh, I should also mention that there is a Castle Windsor facility that loads iBatis up for you so you don’t have to maintain dependencies throughout your application.

So when is using IBatis a good choice? I'll let the IBatis team say it in their own words (taken from the documentation):

So, how do you decide whether to OR/M or to DataMap? As always, the best advice is to implement a representative part of your project using either approach, and then decide. But, in general, OR/M is a good thing when you
  1. Have complete control over your database implementation
  2. Do not have a Database Administrator or SQL guru on the team
  3. Need to model the problem domain outside the database as an object graph.
Likewise, the best time to use a Data Mapper, like iBATIS, is when:
  1. You do not have complete control over the database implementation, or want to continue to access a legacy database as it is being refactored.
  2. You have database administrators or SQL gurus on the team.
  3. The database is being used to model the problem domain, and the application's primary role is to help the client use the database model.
In the end, you have to decide what's best for your project. If a OR/M tool works better for you, that's great! If your next project has different needs, then we hope you give iBATIS another look. If iBATIS works for you now: Excellent!

Oct 2, 2008

Using Mind Mapping to Capture User Stories

I've been doing a fair amount of requirements gathering lately across a number of projects that I've been working on. At the start of each project I needed some way to get a handle on the size of the project and I wanted to do so in a way that improved customer collaboration while helping me structure what the project was all about..

Enter user stories.  For those who don't know - user stories are requirements written in the form of "as a <role> I want <something> so I can <reason>".  They're short one sentence structures that act as a mechanism for drawing out not only what a system needs to do, but also why.  The why often being the thing that is overlooked in traditional requirements documentation.  Stories are also of great use when trying to compile a product backlog and prioritise the order in which work should be carried out.

Now in times past I would've sat down with the customer, opened an Excel sheet or One Note section, and started writing stories right there and then. On the screen.  In front of them.  In one great big long list.

And this works really well.

The customer gets involved in the story writing, in the flow of developing stories and describing roles.  It's engaging and fun and the customers love the involvement.  Now here's the wrinkle - we like to write stories in groups of related items so it's easier to keep track of what our thinking is, but unfortunately people aren't linear creatures.  We tend to jump around, go off on sidetracks and tangents, work our way around a problem, attack it from different angles and generally approach things in a somewhat random but related manner.

When you try recording stories in an excel sheet and you get more than a few hundred of them it starts to get really hard to figure out what stories relate to which parts of a system.  The customer asks "can we go back to where we were talking about thing X? I want to add a few related stories because I've forgotten some stuff".  So we look at the list, realise we can't remember where those other stories were and start searching for keywords until we find the area we want.  Over time it gets kind of confusing.  Also, unless you tag your stories with a functional area they relate to, when you come to collate stories later on you can waste a lot of time and gets things mixed up very easily.  Didn't we cover this already? What should this be related to? etc.

Enter Mind Mapping

Mind mapping, for those who don't know, is a technique where you start by drawing up a few basic ideas and then expanding on those ideas as you think further about them, creating other sub-ideas and so forth.  When you find related ideas you link them together or branch off ideas based on a core theme or concept.  Over time you end up with a whole raft of ideas that are all interrelated and linked in some way.  Mind maps are a great tool for visualising this approach.

So these days when I'm gathering requirements I use this technique but instead of starting with a core idea I start with a placeholder ("the system") and then branch off into the things that people want the system to do. 

Normally people start off with some very high level concepts, and then you start to flesh out those ideas eventually working down into the details. When there is enough detail to write stories in then I start adding the stories directly to the mind map.

Here's an example:

image

Where this gets useful is in the way people think - you can now visually jump around the mind map and easily navigate to where concepts and functionality are located.  Also, you end up talking about things from the customers view - it's their mind map you are helping to draw up.

If you keep at this for a while you can create some fairly large and complex requirements maps - for example the one pictured below has over 1,200 nodes on it yet it's still easy to navigate and find items plus the customer is able to understand what it is that they are asking from the system without getting lost in the details.  I find it hard to do that effectively in an excel sheet, or with story cards alone, so I shudder to think what a struggle it is for my customers.

image 

Don't Forget

Don't confuse things here. A mind map is not the ONLY thing I use for requirements.  I still work with user stories, I still do sizing (though often on the mind map itself), I'll still record stories in excel or TFS or <tool of choice> and I still prioritise them with the customer.

The mind map is just a tool to assist in the effective gathering of requirements, and it helps my customers think through what they want more clearly.  This helps reduce the number of missed requirements and improves understanding between us and I think that's a good thing.

Mind mapping is just one more tool for your agile development toolbox. A useful tool, but not at the exclusion of anything else.

P.S. The software I've used here is FreeMind.  It's a little more structured than some of the other mind mapping tools out there, which I find useful when working through requirements and wish list items.

Oct 1, 2008

Rhino Mocks 3.5 Presentation at ALT.NET

Last night I did a presentation on Rhino Mocks 3.5 at the Sydney ALT.NET user group.  I demoed the new AAA syntax (arrange, act, assert) as well as doing a run through of some of the more advanced usages of Rhino such as using mocks to test events and event handlers, the ability to throw exceptions to see how your class handles them and the use of Rhino from VB.NET.

A big thank you to everyone who came and made it such a great evening.

P.S. The demo project I used last night is available for download here.

Sep 29, 2008

Sydney ALT.NET Starts Tomorrow

This is just a very quick reminder that the Sydney ALT.NET group gets started tomorrow night at 6pm.  More details at http://sydneyaltdotnet.blogspot.com/

Hopefully I'll see you there!

Sep 23, 2008

Brisbane Scrum Users Group

Do you live in Brisbane? Are you interested in Scrum and/or other agile methodologies?  If so you might want to get along to the Brisbane Scrum Users Group.  Kudos to James Brett for getting this up and running, especially outside of Sydney.

If you're in Sydney and you want a regular meet up then get in touch with Lachlan Heasman who is thinking about doing the same here.

Sep 18, 2008

Choosing an ORM When You Can Only Use Stored Procedures

I've been working through some architectural choices with a team starting a new project recently and the ever running debate over database access philosophies came up (as it was bound to).

Personally I'm in favour of letting an ORM manage all the CRUD operations as I see very little benefit in writing CRUD stored procedures (as do others). However I'm also pragmatic and can see some value in the sprocs argument, though the purported benefits of security and performance don't wash with me (but that's for a blog post).

Anyhoo, this particular team decided they wanted stored procedures for ALL data access.  That means CRUD procedures for every table and no direct table access whatsoever.  Yet at the same time they wanted to use an ORM for the .NET side of the equation as coding ADO.NET can be painful at the best of times.

Now, as part of the architecture we had decided early on to use the Repository pattern for data access and ensure we had persistence ignorance for all our data classes.  This lets us isolate the data access plumbing from the rest of the application which helps with the persistence ignorance in the rest of the app, and lets us work with POCO objects everywhere except in the repositories.  However it doesn't solve what to actually use in the repositories themselves.

So what to do? Some of the team wanted to use Linq To Sql, others wanted to use Microsoft's new Entity Framework and others suggested NHibernate.  Too many opinions meant there was only one real way to decide.  We decided to have an ORM to SProcs smackdown - may the best working code win!

The rules were simple... Take a very simple, 3-property, POCO business class and persist it to/from a database using nothing but stored procedures and an implementation of the repository pattern in the ORM of your choice.  Get it done in 4 hours or less.  The team would then vote for their preference.

Here's the results:

Entity Framework

The entity framework has support for stored procedures for data access.  Surely it would be simple to match things up, right? Wrong!! The developer who got the EF mission tried his best to get the tool to do what we wanted but mapping the classes was a problem.

The stored procedure support is best described as simplistic, at it's worst it's probably described using words not suitable for children to hear.

Even when the developer got something almost working, it still required creating a class that duplicated the POCO class and then manually mapping fields from one class to another.  Gah! This is pretty much the same as using ADO.NET and mapping to parameters.

Also, the steps required to get the Entity Framework code "working" were so convoluted and confusing it would be a maintenance nightmare, even if it did work.

No vote was required for this.  Everyone hated it.

Linq To Sql

There was some hope here - a working implementation was shown, however there are some major limitations.

First, Linq to Sql wants access to tables.  Without table access you don't get any change tracking in your data context negating many of it's benefits.

Secondly, the designer support for stored procedures without is limited.  Sure you can drag the procs onto the designer surface, but it only helps a little as the select stored procedures don't actually return classes you can easily use, but rather ISingleResult<T> objects.  To get these into our business layer POCO's we needed to manually map them using either a linq projection or through standard property assignments in code.

Updates via stored procedures were also a problem.  Not having table access means that you won't get any value from implementing the partial UpdateXXX() methods that the linq data context provides as they'll never be called.  Instead you have to call the update stored procedures directly and you have to manually map your objects properties to the stored procedure's parameters.

Further, if you use an insert procedure and database generated primary key fields then you have to remember to get the new value of the key from the database and update the POCO's properties with the new value.

It's workable, but no one in the team was that impressed with it.  It received zero votes.

NHibernate

The implementation using NHibernate was also shown to be workable.

A hibernate mapping file was created that had a class definition with specific overrides for the update, insert and delete methods so they called out to stored procedures.  There was also an override for the object loader to use a select stored procedure.

The only change to the POCO was that the properties needed to be changed so that they were virtuals.  We need to investigate this a little more but I'm going to assume it's something to do with NHibernate creating proxy versions of the classes for internal use.

Other than that the actual repository implementation was very simple.  Pass an object to NHibernate's session and call Flush at the appropriate times.

When a vote was called for everyone went for this method.  If I get some time I'll try and explain how it all works (or you could just do a Google search for it!).

 

Conclusion

So NHibernate method wins, but the scenario was simplistic.  There may be some further issues that we need to deal with such as complex procs, optimistic concurrency and so forth, but even so there is more confidence that NHibernate will deliver the goods.  It has a large user base, it's been around for quite some time now and we're pretty sure other people have tried this before.

On the other side of the equation, Linq to Sql and the Entity Framework are surprisingly and embarrassingly inept at this.  If you don't have direct table access then you might as well forget about using these tools and stick with ADO.NET or code generation.  The simple fact that data access via just stored procedures is such a common requirement in enterprise databases and that these two "modern" offerings from Microsoft just don't work is downright perplexing.  Seriously, Microsoft recommends for years that people use stored procs and the release tools that are only partially functional in a pure stored procedure environment. What gives?!

Well, I think that's enough of a rant for now - time to get some back to doing some real work now!

Sep 16, 2008

The Twitter Build Publisher is now up on CodePlex

I posted previously about the Twitter Build Publisher (aka the BuildTweeter) - a little utility that lets you publish build results and quality change events from Team Foundation Server and Team Build to Twitter.

Well I've finally managed to find enough time to put the project up on codeplex for public consumption.  If you want to grab a copy of it, mosey on over and download a copy now from http://www.codeplex.com/BuildTweeter/ and feel free to contribute.

Sep 8, 2008

Sydney ALT.NET First Meeting will be September 30th

I'm happy to let you know that we now have some details for where and when the ALT.NET user group meetings will be.

We will be meeting on the last Tuesday of every month at the Thoughtworks offices in Sydney. Many thanks go to Thoughtworks for letting us make use of their facilities. Their generosity is greatly appreciated.

Where:

Level 8, 51 Pitt Street
Sydney NSW 2000 Australia

[Map]

When:

Tuesday, September 30th

6pm - 8pm

What:

Welcome & Latest Happenings

Presentation 1 (30 mins)

Break for food & socialising

Presentation 2 (30 mins)

We'll have the 2 presentations finalised in the next few days, however if you've got anything you'd like to see discussed, please bring your ideas along.

We look forward to seeing you there and please spread the word!

Sep 6, 2008

Tech.Ed Australia 2008

Tech.Ed Australia is over for another year and for me this Tech.Ed was very different to the others I have been to.  Previously I have attended as a delegate an I've simply gone to sessions and absorbed as much information and opinions from the presenters as I could.

This year I was fortunate enough to be given a breakout session on the Architecture track in which I talked about Dependency Injection, Inversion of Control and Unity (the IoC container that is part of enterprise library 4).  I also had a "chalk and talk" session where I gave a 20 minute version of my agile agile presentation.

Both sessions were well attended and for everyone who came and especially to those who gave me constructive feedback, I'd like to pass on a big thank you.

Apart from my sessions I also spent time getting the TFS environment and automated build and deployment scripts set up for the Tech.Ed DevGarten project where we were redeveloping the UNICEF web site, and I spent a fair bit of one-on-one time with some of the conference delegates who wanted to talk about either unity or agile development.

As for the other breakout sessions I only made it to a handful - I went to Scott Hanselman's presentation on ASP.NET MVC so I could pick up some tips on presentation style, a session on dynamic languages (Iron Python, Iron Ruby, etc) and one on F# so I could get expand my thinking beyond C# and VB.NET, and also one on managing complex development as I've worked with one of the presenters and was curious to see what would be said.

All up I thought it was a great tech.ed and I'd like to thank Microsoft and the DPE/Marketing teams for organising such a great event. Well done to all!

Sep 2, 2008

A Generic Command Pattern in .NET 3.5

The command pattern can be a powerful thing to use and yet it can be a right royal pain in the ar... let's just say it's annoying to implement it at time.  Why? Because each individual command needs to be represented as an object and in a system that supports many commands you end up with a class explosion.

For those of you who need a refresher on the command pattern it is stated as follows:

The command pattern encapsulates a request as an object, thereby letting you parameterise other objects with different requests, queue or log requests, and support undoable operations.

Yeah, great - OK so in plain English that means you create classes to represent commands and those command classes simply make calls to other objects when you execute them.  It's a fairly simple pattern.

So let's take as an example the command pattern implementation from the awesome Head First Design Patterns book and implement it in .NET instead of Java.

First we declare an interface for our command objects:

    public interface ICommand
{
void Execute();
}

Then we create a command to turn a light on:

    public class LightOnCommand : ICommand
{
private Light light;

public LightOnCommand(Light light)
{
this.light = light;
}

public void Execute()
{
light.On();
}
}

And finally we create a simple remote control class:

    public class SimpleRemoteControl
{
private ICommand slot;

public void SetCommand(ICommand command)
{
slot = command;
}

public void ButtonWasPressed()
{
slot.Execute();
}
}

So now if we wanted to use this in our code we could have a test like the following:

[TestMethod]
public void BasicExecuteTest()
{
SimpleRemoteControl remote = new SimpleRemoteControl();
Light light = new Light();
LightOnCommand lightOn = new LightOnCommand(light);
remote.SetCommand(lightOn);
remote.ButtonWasPressed();
Assert.IsTrue(light.IsOn);
}

Easy enough.  But now, let's say we want to add a command to turn our light off.  We would have to implement a new LightOffCommand class.  If we were using a TV remote we would then need commands for each of the channels, the volume buttons, a channel up/down button, an input selector, etc.  As you can imagine once you start creating a class per command you can easily end up in with hundreds of classes all of which look pretty much the same.


This is where generics and lambda expressions in .NET 3.5 can help us.


Let's take our ICommand interface and implement it with a generic class:

public class Command<T> : ICommand
{
private T target;
private Action<T> command;

public Command(T target, Action<T> command)
{
this.target = target;
this.command = command;
}

public void Execute()
{
command(target);
}
}

We now have a single class that is able to represent a whole range of commands without getting us into the class explosion situation we had previously.


The Action<T> command is a variable that will hold a lambda expression that doesn't return a value.  If we wanted a value returned we would need to use Func<T, TResult> instead.


When we want to create a command we now pass the object we want to take action on, as well as a command to execute. So now we can refactor our test and change it as follows:

[TestMethod]
public void BasicExecuteTest()
{
SimpleRemoteControl remote = new SimpleRemoteControl();
Light light = new Light();
var lightOn = new Command<Light>(light, l => l.On());
remote.SetCommand(lightOn);
remote.ButtonWasPressed();
Assert.IsTrue(light.IsOn);
}

So here we see that the LightOnCommand has been replaced with the new generic command Command<Light> command and that we are passing the object to target with our command as well as a lambda expression for the command itself.


What this means is that we can now declare commands as follows without needing to create individual classes for each command:

var lightOff = new Command<Light>(light, l => l.Off());
var strobeLight = new Command<Light>(light, l =>
{
l.On();
l.Off();
l.On();
l.Off();
l.On();
});

So much nicer!


We now have an implementation of the command pattern that is not only powerful, but much easier to code and maintain as well.


Of course, if there's a lot of command reuse in your application this implementation of the command pattern might not be for you as it could easily lead to cut & paste development, though with judicious use of an IoC container you should be able to overcome that particular issue.

Aug 29, 2008

Do You Want An ALT.NET Group In Sydney?

I'm gauging interest on starting an ALT.NET group in Sydney.  I've tweeted about it, and posted on the altdotnet mailing list to see who might be a part of it and so far things are looking good.  I figure I might as well blog about it as well :-D

Now in case you don't know what I'm talking about, here's a definition of ALT.NET:

  • You’re the type of developer who uses what works while keeping an eye out for a better way.
  • You reach outside the mainstream to adopt the best of any community: Open Source, Agile, Java, Ruby, etc.
  • You’re not content with the status quo. Things can always be better expressed, more elegant and simple, more mutable, higher quality, etc.
  • You know tools are great, but they only take you so far. It’s the principles and knowledge that really matter. The best tools are those that embed the knowledge and encourage the principles

If you'd like to be a part of something like this, then leave a comment so I know who to get in touch with.

If there's enough interest to make it worth kicking off it'll then just be a matter of sorting out the logistics (i.e. finding a location, date & time, etc) and getting the message out.

Scrum Gathering on Monday & Tech.Ed Australia Starts Wednesday

Just a reminder of a few things happening next week.

First, there is a Scrum gathering on Monday night - http://www.scrum.com.au/2008/08/25/sydney-scrum-users-get-together-september-1 and it looks like the Syxpac user group will also be joining us.  It should be a fun night.

Secondly, Tech.Ed Australia starts on Wednesday.

If you're interested in seeing my session on building loosely coupled applications with Unity (ARC304), it's on Thursday at 11:45.  If you just want to catch up with me feel free to get in touch via the connect site, or email me.

It should be a long, tiring, enjoyable week :-)

Aug 24, 2008

Online Tipping

I just noticed a post by Seth Godin riffing that Ads are the new online tip jar.  He says that "If you like what you're reading, click an ad to say thanks." which resonates quite well with me because this is what I've started doing over the last few months.

It doesn't take much to click an ad, wait for a page to load, then use the browser back button and get back to what you were doing.  Takes a few seconds, and give the site creator something small in return.  It's an easier system than Sourceforge's donation mechanism, or the many forms of micro-payments (which just never seem to take off) so for now, clicking ads seems to be the best option.

Note: Whilst I do have ads on this site I don't want you to click them just because you read this post.  I'm not trying to drum up revenue.

Aug 22, 2008

Clone Detective for Visual Studio 2008

I just ran across a new project on CodePlex today called Clone Detective for Visual Studio from Immo Landwerth (also responsible for NQuery) and I've got to say that it's really quite cool.  I've blogged previously about detecting code clones with CCFinder but CCFinder is an external tool and a bit cumbersome to set up and use.

Clone Detective for VS may not be quite as powerful but it is incorporated into VS and is so much easier to use that it will probably become my tool of choice as a result.  It's so much better if you can detect your copy & paste development efforts in the same tool that you can fix them in.

Here's a quick screenshot of what it looks like:

image

We get 3 new windows we can look at (available from the View menu).

The Clone Explorer is where you initiate clone detection, and see results.  E.g. the AlternateTaxRules.cs file has 2 cloned sections.

The Clone Intersections looks at a file and shows you all the other files that share clones with it.  The different colours represent the different clones sections.

The Clone Results shows you an individual cloned piece of code and where it resides throughout the application (i.e. all the different files where  that same code occurs).

When you look at a file with clones you'll see a purple line next to the cloned lines (shown in the image).  By default visual studio just shows a single source file in the main window, however by dragging the tab with the filename in it to the right you can get to a side-by-side view which makes it so much easier to compare the clones before deciding it you should refactor or not.

From first impressions it looks to be a handy little tool and definitely one to keep in my VS toolbox.

Publish TFS Build Information to Twitter

I've put together a simple application to publish build status information from Team Foundation Server to Twitter.  It's built as a windows service that listens for the various build status events from TFS and tweets information depending on the event it receives.  At its core it uses the Readify.Useful.TeamFoundation.Common assembly from TFSDeployer for listening to the TFS events and the TwitterN library from amptools for talking to Twitter.

At the moment the application is still very much an alpha with things like error handling and customisation of messages not done as yet.  Even so, here's what some working results on Twitter:

image

If you're interested in getting a copy for yourself let then me know and I'll put the project up on codeplex.

Aug 20, 2008

An Introduction to Microsoft's ALM (Application Life-cycle Management)

Last year Microsoft launched the "Microsoft Application Platform".  The application platform is Microsoft's vision for how businesses can use Microsoft technology to improve information & knowledge management within their organisation and focuses on 5 key areas as follows, each of which wraps a number of Microsoft product & services offerings:

  • Business Intelligence
  • SOA & Business Process
  • Development
  • User Experience, and
  • Data Management

I'm not going to iterate through the various products that sit under each umbrella, instead I'm going to drill into the Development area as that's the one I find most interesting.

Development Platform

The Development area of the application platform is actually called Development & Application Life-Cycle Management, and normally gets tagged with the ALM acronym.  The good news is that this isn't just an attempt by Microsoft's to sell you on their tools (though obviously that's a major element of it) but it's also an acknowledgement that good processes and practices need to be followed to ensure that applications don't cost an arm and a leg to not only develop, but also to maintain in the future.

From a Microsoft ALM whitepaper comes this little gem: "Acquiring tools to support ALM, such as Microsoft® Visual Studio® Team System (VSTS), is straightforward. Introducing and driving an ALM strategy within your organization, and understanding the necessary changes required within your business, is more difficult."

The introduction section of the same whitepaper talks to the fact that project failures can be traced to a limited number of root causes described as:

  • Lack of visibility into project status
  • Ineffective Team Communication
  • Balancing Business Demands with Project Risk
  • Unpredictable Delivery Times and Quality

These are all valid and legitimate issues.  Issues which both traditional and agile development methodologies attempt to resolve.

What is ALM?

Microsoft's ALM offering is a combination of both development processes and supporting software to help automate whichever ALM provided process you follow.  In the ALM offering Microsoft have included processes for both agile and traditional development models.

Because technology is always on the move a normal development methodology won't specify what technology a team should use, just the processes and practices to follow.  A team can be using .NET, Ruby, Java, PHP, Cobol, whatever.  The difference with ALM is that even though it includes methodologies to follow, it also includes tools and technologies to support those methodologies - namely Visual Studio Team System (VSTS).

Knowing that VSTS is part of the Microsoft ALM offering it might be easy to fall into a trap of thinking that ALM is just VSTS by another name. It's not.  VSTS in and of itself does not require any specific development process.  It is designed to help you automate your development activities now matter what they might be.  How a team then uses VSTS is up to them.  In fact, you can easily find teams using VSTS that have a development process as loosely defined as "write code and see if it works".  That's not something that can be considered as ALM, simply because it fails to address the project management aspects of application development.

How Does VSTS support ALM processes?

So, knowing that VSTS is part of the ALM offering, how does it help? What should the ALM support tool offer us?

According to Wikipedia, ALM offerings are generally expected to cover the following features:

  • Requirements Visualization
  • Requirements Management
  • Feature Management
  • Modelling
  • Design
  • Project Management
  • Change Management
  • Configuration Management
  • Build Management
  • Testing
  • Release Management
  • Deployment
  • Monitoring and Reporting
  • Workflow

And VSTS offers support for all of these items.

Project Management, Requirements Management, Change Management, etc are all process/methodology related items and Team Foundation Server includes process templates for both agile and traditional development methodologies (the MSF Agile and MSF CMMI templates) as well as letting you plug in your own process templates if you wish to use an alternative methodology (e.g the Scrum template).

For more info on VSTS and how it supports ALM have a look at the Team System site.

 

It should be noted that Microsoft has an online assessment tool to help you gauge how well you are performing Application Life-Cycle Management.