Archive for the ‘microsoft’ tag
The recently released Oxite code base has taken a bit of a hammering in the blogosphere for a variety of reasons – the general feeling being that it doesn’t really serve as a particularly good example of an ASP.NET MVC application.
I was intrigued to read the code though – you can always learn something by doing so and reading code is one of the ares that I want to improve in.
So in a style similar to that of a Technical Retrospective these are my thoughts.
Things I like
- The Repository pattern from Domain Driven Design is used for providing access to the entities and provides encapsulation around the LINQ to SQL code.
- There is some quite clever use of extension methods on FormCollection in the AdminController to create Posts and Tags from the data collected from the page. There are others as well – the developers really seem to grok extension methods in a way that I currently don’t. It will be interesting to see if I start using them more as I code more with C# 3.0.
Things I’d change
- Testing wise there are some tests covering the MetaWeblogService class although it feels like the setup in each of the tests is a bit heavy. I’d refactor the tests using compose method to try and remove some of the noise and rename the tests so that they follow the BDD style more closely.
- When time is used in the code it is done by directly using the DateTime class. Testing time based code is made much easier when we can control the time in our tests, so have a Time Provider or System Clock class can be a very useful approach here.
- A classicist approach has been taken towards testing with no mocks in sight! It feels like a lot of work went into creating the fake versions of the classes which could maybe have been done much more easily using a stub in Rhino Mocks for example.
- A lot of the ViewData code is weakly typed by putting values into an array. We started with this approach on a project I worked on and it’s so easy to misspell something somewhere that we came to the conclusion that if we can get strong typing we should strive for that. Jeremy Miller’s Thunderdome Principle works well here.
- AdminController seems to have a massive number of responsibilities which is perhaps not surprising given the name. I think it’d be better to have the administrative tasks handled from the individual controllers for those tasks. This would also help lead the design towards a more RESTful approach
- The Domain model is very driven from the definition of the database tables from my understanding. The domain objects are effectively representations of database tables. If we want to create a richer domain model then it would make more sense to design the classes in terms of what makes sense in the domain rather than what makes sense at a database level. An ORM tool could then be used to map the database tables to the code.
- A lot of the domain objects implement an interface as well which I don’t think is really necessary. Although there are exceptions, in general when we refer to domain objects we care about the implementation rather than a contract describing what it does.
- The Routes collection is passed around quite a few of the controllers, seemingly so that URLs can be generated inside other pages. It seems a bit overkill to pass this around to achieve such a simple goal and my thinking is that maybe a wrapper class which generated the URLs might be more intention revealing.
- There is a bit more logic than I’m comfortable with in some of the views – I think it would be good to move this logic into ViewModel classes. This will have the added benefit of allowing that logic to be tested more easily.
Want to know more about
- I’m curious as to why LINQ to SQL is being used as the interface to the database as I was under the impression that it is being phased out by Microsoft. The syntax seemed quite readable but I think the problem of interacting between code and the database in a clean way has been largely solved by NHibernate although the Entity Framework is a newish addition in this area.
- One interesting thing I noticed was a lot of Background Services running in this codebase – I’ve not come across this in a web application before. They are actually being used for creating trackbacks, sending trackbacks and sending email messages.
My learning from reading the code
- I asked for some advice on the best way to read code on Twitter and the most popular advice was to debug through the code. Unfortunately I couldn’t seem to do this without having a database in place so another approach was necessary. Instead I started reading from the tests that were available and then clicked through to areas of interest from there. I think it worked reasonably well but it wasn’t as focused as if I had debugged and I couldn’t see the state of the program as it executed.
- I wanted to find a way to read the Oxite code and navigate to areas of the ASP.NET MVC source using Reflector without having to do so manually. TestDriven.NET was recommended to me and it worked really well. Clicking the ‘Go to Reflector’ option from the menu takes you to the current class in the Reflector window. Impressive.
- Changing the Resharper find usages menu to show ‘Namespace + Type’ makes it much easier to try and work out what the code is doing rather than the default setting of just ‘Namespace’.
- From looking at some of the ASP.NET MVC code I realised that a lot of data is stored in static variables in order to make the data globally accessible. It’s something I had never considered this before and it makes sense in a way but feels a little nasty
- I found that I was getting side tracked quite a lot by irrelevant details in the code. I’m used to having a pair guide me through a new code base so looking at this one alone was a bit different for me. Separating noise/signal when reading code and identifying common patterns to allow me to do this is something I am working on.
I think it’s really cool that the Oxite team put their code out there for people to look at and learn from. A number of highly experienced developers have made suggestions for improvement so clearly this is quite a useful way to get feedback and code better in the future.
From what I understand, Rob Conery is working on some refactorings for this code base so it will be interesting to see what it looks like when this is done.
I went to see Object Mentor’s Dave Thomas give a talk about cloud computing on Tuesday evening in a combined meeting of the Sydney Alt.NET user group and several others.
I’d not seen him speak before but several colleagues had seen him at JAOO earlier this year so he came highly recommended.
We started off with a plug for the JAOO Australia 2009 conference which will again be in Brisbane and Sydney at the beginning of May. I’ve not been to a JAOO conference before but just looking through last year’s slides and looking at the quality of the speakers is enough to tell you it’s worth attending.
After that we moved onto his view on cloud computing, which I’m told was quite similar to one he gave at JAOO called ‘Next Generation IT – Life After Jurassic Middleware‘.
I’ve heard about cloud computing but not much more beyond that so it was quite the learning experience for me. Some of the more interesting things he spoke about:
- The opening part of the presentation spoke of the pain that we have created for ourselves in the software world with over complex solutions to problems which the majority of the time are just moving data from A to B and doing CRUD operations. He was particularly damning of Java and ORM in this section of the talk.
- The main idea around cloud computing was that we should be able to develop and deploy applications quickly. We shouldn’t have to rely on a production support team to deploy and take care of our application i.e. throw it over the fence, but should take responsibility for it. Deploying to the cloud gives us the ability to do this.
- Services should be all about having a simple API and hiding the complexity behind this so that the consumer doesn’t have to worry about it. I guess this ties in quite tightly with encapsulation, but he spoke about the leaking of complexity that we see in many APIs which make them much more difficult to use.
- One idea I found interesting was that of exposing legacy systems as atom feeds. We often spend a lot of time trying to add tests around these systems to allow us to add new functionality, but this approach seemed to suggest just using them for their data and writing the code elsewhere.
- In response to a question about some of the new features being planned in Java 7, he spoke of the need to choose the right language for the job and his dislike of the current trend for object oriented languages to support functional programming concepts. The obvious thoughts here for me were that when it comes to parallel computing Erlang is best, for web development, Ruby, for client side development, C#. Of course we don’t always have the choice when it comes to language as clients have to maintain what we have written but in an ideal world his ideas make sense.
Overall a humorous and interesting talk and one that has made me intrigued to learn more about cloud computing.
I’ve been having trouble trying to work out how to build our projects in msbuild in release mode without creating the customary pdb files that seem to be created by default.
I tried calling msbuild.exe with the ‘Release’ configuration:
'C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.Exe ( Proj.csproj /p:OutputPath=\output\path\ /p:Configuration=Release)'
To no avail. It still created the pdb file. Next I tried setting the ‘DebugSymbols’ property to false:
'C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.Exe ( Proj.csproj /p:OutputPath=\output\path\ /p:Configuration=Release /p:DebugSymbols=false)'
Still it created the file. Finally I found this post which suggested that you actually needed to make the change in the Proj.csproj file itself.
I changed this part of the file so that DebugType is now ‘none’. It had a value of ‘pdbonly’ when I opened the file.
none true bin\Release\ TRACE prompt 4
The pdb is no longer created.
This can also be done by passing /p:DebugType=none as a command line argument as Tim points out in the comments.