james mckay dot net
because there are few things that are less logical than business logic

Posts tagged: visual studio

Keep the number of projects in your solution to a minimum

There are a lot of common practices among .NET developers that get touted as “best practices” although they are nothing of the sort. A lot of them seem to be leftovers from the days about ten years ago when there was a lot of hype about n-tier although the people promoting n-tier didn’t properly understand the problems that n-tier was supposedly trying to solve. One such example is too many projects in a single solution.

In general, you should always aim to keep the number of projects in your solution to an absolute minimum. For a simple web application, your solution requires exactly two projects: the application itself and your unit tests. For an application with a web front end and a console application, your solution requires four projects: the shared components, the web front end, the console application, and your unit tests. Products that deploy different applications to different servers may need one or two more for shared components, for instance, but the number should still be kept as small as possible.

Your solution does not — I repeat, does not — require separate projects for your controllers, your model, your business services, your repository, your shared components, your interfaces, and your wrappers round third party web services.

Your solution does not require multiple unit test projects. Some people create a separate unit test project for every main project in their solution. This is completely unnecessary: why not have a single unit test project for all of them? Of course, it may be worth having one project for fast unit tests, and another one for slower tests that need to run against a database, but over and above that, reasons for creating extra test projects are few and far between.

Your solution does not require multiple front end applications of the same type for deployment on the same server. You may need a back-end admin application on one server and a front-end public facing website on another, but you don’t need two back-end admin web applications for the same solution.

There are three reasons why too many assemblies are harmful:

1. Too many assemblies slow down compilation. When you have to compile a single project that references thirty external dependencies, the C# compiler only has to pull in these referenced assemblies once. When you have to compile thirty projects that reference thirty external dependencies each, the C# compiler has to pull in all thirty dependencies every time — a grand total of nine hundred referenced assemblies. This adds a lot of time onto your edit-compile-test-loop, which in turn knocks you right out of the zone and makes the whole development process feel like wading through treacle.

2. Too many assemblies make dependency management a pain. If you have to add a third party reference to thirty different projects, it is a massive, painful violation of DRY. If you have to swap out one reference for another, it is painful. If you have to add a third party reference to only a subset of those thirty, it is even more painful because you have to work out which assemblies require it and which don’t. And don’t even get me started on the problems you might face if you end up with two different projects referencing the same assembly from two different places within the bowels of your third party dependencies directory.

3. Too many front-end projects in particular make configuration and release management a pain. If you have two web front end projects for deployment on the same server, you have to configure them both together and deploy them both together. The more configuration you have to manage, the greater your risk of making a mistake. When you add a new configuration option, you have to update several different applications, and you increase the risk that you might miss one. If you have to change Copy Local from False to True for some assembly or other, you have to go through all your front end applications to make sure this is done correctly. Again, it’s a violation of DRY.

The main reason why people advocate a lot of projects in their solution is to attempt to keep the different logical parts of their code separate, so, for instance, they aren’t referencing System.Web from within the data access layer, or the data access layer directly from the UI, and they aren’t introducing circular dependencies. In practice, it simply isn’t worth it. If dependencies between your classes and namespaces really bothers you, a far simpler alternative is to buy a licence for NDepend instead. Certainly, you should have a very, very good reason to add a new project to your solution, and you should look to see what you can consolidate wherever you can.

Tourists and residents, Visual Studio and vim

My blog post on Silverlight seems to have attracted quite a bit of attention from the Silverlight fans. Silverlight has quite a devoted following among many .NET developers: after all, you get one language and platform for everything from the front end through to the back end, you get IntelliSense, you get Resharper, and you get some awesome visual tooling. It also offered a hope that perhaps some day we might be able to ditch HTML and JavaScript altogether and build websites in XAML and C#.

A lot of .NET developers hate JavaScript, and indeed all other dynamic languages such as PHP, Ruby and Python, because you don’t get the IntelliSense, the drag-and-drop support, and so on. Even the best of us — people of the calibre of Jeremy Miller or Ayende — struggle without Resharper, as Rob Conery noted:

Finally – I can’t tell you how ironic I continue to find it that the people who rip apart visual tooling cannot, I repeat cannot function PERIOD without Resharper. I wanted Ayende absolute fumble when we coded together, and Jeremy Miller was just about… no he was completely… USELESS without it.

Yet PHP, Python, Ruby and JavaScript developers never have a problem with this. Poor support for IntelliSense never seems to bother them. Inconsistent conventions, such as whether $needle or $haystack comes first — perhaps the number one criticism levelled at PHP by .NET developers — are regarded as pretty much a non-issue. Developers working with dynamic languages are happy to put up with editors and IDEs that Visual Studio users would consider primitive.

Just try introducing your average .NET developer to vim. They’ll freak out.

Whoa! A console-based application! No IntelliSense! It doesn’t even have any drop-down menus! What is this, the Dark Ages? How do I edit things? How do I get out of it? How do I get help?!

Yet vim — and its equally mystifying arch-rival emacs — are incredibly popular outside the mainstream .NET community, as too is the command line. In fact, many non-.NET developers actively dislike some kinds of graphical tools, instead, preferring the command prompt. That’s probably why Joel Spolsky’s Mercurial tutorial, hginit.com, uses the command line almost exclusively. Visual Studio is perceived as a bloated, slow, YAGNI-fest, and the end-to-end integration of Team Foundation Server is dismissed as snake oil. Why?

It’s a case of two completely different mindsets.

When I was younger, one of my hobbies was learning German. I was never much good at it, mainly because I didn’t get as many opportunities to practice it in real life as I would have liked, but I did end up going to Germany a handful of times on some short (4-5 day) trips.

One thing I learned about Germany is that going there for a short visit is not quite as effective at teaching you the language as you would expect. A huge proportion of Germans speak very good English, and they will switch to it faster than IntelliSense can replace if with IFormatProvider at the slightest hint that you are struggling. English is cool in Germany.

For example, on one occasion, we were travelling up the Rhine by train when der Schaffner came into the carriage inspecting tickets. “Fahrkarten, bitte,” he said.

I handed over my ticket. He looked at it.

Haben Sie einen Zuschlag gezahlt?” he said.

At this point, my schoolboy German deserted me. I hadn’t the foggiest what ein Zuschlag was. Nevertheless, determined not to let the fact that I was linguistically challenged get the better of me, I made a wild guess that it was something to do with changing trains (as we had done in Karlsruhe), completely forgetting that I already knew that the word for changing trains is umsteigen, which most certainly isn’t ein Zuschlag. But when you’re as bad at German as I am, all those words beginning with um and zu tend to sound a bit too much like each other anyway.

Wir haben, um, zugeschlagen…

The conductor decided, in the light of the fact that I was struggling to speak nonsense, that some IntelliSense, aka English, was in order. “The supplement?”

Okay. So der Zuschlag is the supplement that you have to pay for reserved seats on German trains. I dug out the Zuschlag ticket, showed it to him, and he was on his way.

Now it’s one thing when you are only visiting a foreign country for a few days and either (a) staying with English-speaking friends, or (b) doing touristy things like travelling up the Rhine by train. It would be a completely different matter if you went there to live permanently. As a British or American expatriate living in a foreign country, you could get away without learning the local language and with relying on phrasebooks and English-speaking friends. But it would be much harder. After all, you would have to deal regularly with all sorts of people and situations. People like estate agents and lawyers and councillors and traffic wardens and pastors and doctors and car salesmen and vets and school teachers and politicians and telemarketers and social workers and employers and clients and creditors and bank managers and next door neighbours and kids accidentallyonpurpose kicking balls over your fence asking if they can come and retrieve them and people in Krähwinkel who have lived in the same house all their lives. People whose interactions with monolingual Brits and Americans are few and far between, and consequently have less of an inclination or opportunity to learn English.

Vim, emacs and the command line are like that. They take you right out of your comfort zone and force you to actually learn the vocabulary that you’re using in your code. You learn whether $needle or $haystack comes first in PHP, just as you would learn the difference between der Leiter and die Leiter in German. It sticks in your mind sooner, you become more familiar with the intricacies of the language, and you are more likely to be able to say, at an earlier stage, “Oh yes, there’s a word — a method — for that somewhere.”

By making us reliant on the IntelliSense phrasebook, Visual Studio encourages us to think like tourists. By forcing us to learn the language, on the other hand, Vim, Emacs and dynamic typing make us think like permanent residents.