Everyone who talks about ASP.NET MVC gets asked the question:
Should I use MVC or Web Forms?
There’s been quite a bit of debate on this topic, but in a couple years I don’t think it will matter.
… those who can count in binary, and those who don’t care.
The IT developer who doesn’t read blogs and works 8 hours a day in a Microsoft shop is either portrayed as a hero who produces business value, or vilified as a duct-taping Mortimer who produces a mess. The truth is somewhere in the middle, and the fact is that these developers look at MVC and Web Forms and see this:
… which is why so many people ask the question. There is no clear distinction. Most developers don’t have a passion for TDD or composite UIs – they just want to get the day’s batch transactions through the firewall and into a spreadsheet for the business folks. “I see two web frameworks. I can use either. Just tell me which one is best!!”.
Meanwhile…
There was a big SharePoint conference last week, and SharePoint is clearly positioning itself for global feature domination.
When you stack up SharePoint versus MVC or Web Forms, then everyone can see a contrast. One is a small framework to build on. The other is a giant platform that moves tons of data across the corporate landscape.
The SharePoint platform is an out-of-the-box-do-everything solution you tweak and augment for a particular environment. Some developers think this is great. Some developers think this is scary. At least the contrast makes for an easy decisions.
… those who like frameworks, and those who like platforms.
Developers who like platforms will want to use SharePoint. Install it. Customize it. Then watch end users collaborate in spreadsheets on numbers from Analysis Services.
Developers who like frameworks will want to use MVC. It’s light. It’s extensible. It leaves them in complete control.
Web Forms is caught in the middle. The abstraction is too heavy for framework lovers. At the same time, it’s not an out-of-the-box solution despite all the drag-n-drop data controls and pre-configured providers. It’s vulnerable to both sides and both SharePoint and MVC have momentum and excitement.
The question in the next decade won’t be: “MVC or Web Forms?”.
The question will be: “MVC or SharePoint?”
But nobody will ask the question, because the answer is easier to figure out.
I am a founder and Principal Consultant with OdeToCode LLC. I have 19+ years of commercial
software development experience across a wide range of technologies.
I’ve successfully delivered software products for embedded, Windows, and web platforms.
I’ve developed web services for Fortune 50 companies and firmware for startups.
I’m a published author in leading print and online technical journals, and
I'm also a speaker at national and international conferences.
I’m available for consulting on .NET related projects anywhere through OdeToCode LLC. These days I primarily work with C#, ASP.NET, ASP.NET MVC, and SQL Server. I also enjoy writing articles and white papers. Contact me as scott at odetocode.com.
I enjoy writing about technology. I've been fortunate enough to work with some of the best editors and publications in the world.
Over the years I’ve worked with some of the best trainers in the world at Pluralsight. I’ve delivered over 25 weeks of class instruction and produced over 50 hours of video content. Here are the current classes and training courses I offer.
This course will give you everything you need to start building applications using the ASP.NET MVC framework. Working through a series of practical examples, you’ll see how to use framework components, scaffolding, Razor views, and jQuery UI widgets. We’ll talk about best practices for real world scenarios and highlight key extensibility points in the MVC framework.
The course is designed to take experienced developers who are new to .NET or the C# language and give them all the fundamentals, best practices, and advanced knowledge required to be a productive and happy developer with the C# language. We’ll demonstrate all the capabilities and features of the language, and work with both desktop and web applications to see how to apply the language in different contexts. During the course we’ll solve specific, everyday problems in application development using techniques like functional programming and test-driven development. We’ll also see how to apply modern programming principles and use dynamic programming techniques to make the most of the C# language.
LINQ changes how we build data access components with .NET, and also introduces new flexibility and expressiveness Into the C# language. In this course we’ll see how LINQ works at a language level, and also how to use LINQ with XML and the Entity Framework. We’ll look at the tradeoffs to evaluate when building a data access layer with LINQ, and see how to use LINQ features in a domain model to implement better business logic.
This course will demonstrate the features and capabilities of the latest web standards: HTML 5 and CSS 3, as well the latest JavaScript libraries that will help you build great applications on top these standards. From local storage and video, to geo-location and background workers, we’ll have a thorough exploration of each area and see practical examples and advice.
Optional Content:
This course teaches and demonstrates the test-first development approach to building software. We’ll discuss the value of unit testing and uncover the essence of the red-green-refactor workflow. The course will also examine various styles, techniques, and tools used by test-first development teams.
Presentation mode isn’t new (it was introduced in Vista), but it is handy. One easy way to turn presentation mode on is to type “present” into the Start menu search box and let Windows find the “Adjust settings before giving a presentation” item.
From here you can turn on presentation mode and tweak some settings.
Update: As Jim O’Neil points out, you can also use Windows+X key combo to launch the mobility center and then it’s one click to turn on presentation mode. I learn a new shortcut key everyday…
Notice the help text says “your computer stays awake”. I turned on presentation mode today just to keep my laptop awake while it sat in a corner coping a 16 GB file over WiFi.
Of course, presentation mode is useful when you have an actual presentation, too. In addition to the background, screen saver, and volume settings, Messenger will mark your status as busy and not throw toast on the screen (you’ll only get a blinky icon in the taskbar). Other applications can disable their notifications, too, but the author of the application has to write the code to be aware of notification state. Kirk Evans has an example.
Unfortunately, presentation mode is only available on laptops by default. It turns out you can do a fair amount of presenting from a desktop with Camtasia (love it) and Shared View.
The good news is you can have presentation mode on a desktop with just a couple registry tweaks: http://www.dubuque.k12.ia.us/it/mobilitycenter/
presentationsettings.exe is the name of the executable that displays the dialog shown above. If you want to toggle presentation mode from a script you can use:
presentationsettings /start
and
presentationsettings /stop
Another handy executable is mblctr.exe. This program launches the Windows Mobility Center with a UI to tweak brightness, power settings, presentation mode, and more.
This concludes my exuberant Windows tip of the day, I hope you found it useful.
I’m looking at 5-7 files of data in CSV format. The columns and format can change every 3 to 6 months. What I wanted was a strongly type wrapper / data transfer object for all the CSV file formats I had to work with, and I thought this would be a good opportunity to try a T4 template.
If you haven’t heard of T4 templates before, then it is a technology that is worth your time to investigate. Hanselman has a pile of links in his post T4 (Text Template Transformation Toolkit) Code Generation – Best Kept Visual Studio Secret.
Each CSV file I’m working with has a header row:
PID,CaseID,BirthDate,DischargeDate,Status …
1001,2001,1/1/1970,6/1/2009,Foo …
… and so on for ~ 100 columns.
I wanted a template that could look at every CSV file it finds in the same directory as itself and create a class with a string property for each column. The template would derive the name of the class from the filename. Here’s a starting point:
<#@ template language="c#v3.5" hostspecific="true" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Collections.Generic" #> using System; namespace Acme.Foo.CsvImport { <# foreach(var fileName in GetCsvFileNames()) { var fields = GetFields(fileName); var className = GenerateClassName(fileName); #> public class <#= className #> : ImportRecord { public <#= className #>(string data) { var fields = data.Split(','); <# for(int i = 0; i < fields.Length; i++) { #> <#= fields[i] #> = (fields[<#= i #>]); <# } #> } <# foreach(var field in fields) { #> public string <#= field #> { get; set; } <# } #> } <# } #> } // end namespace <#+ private string GenerateClassName(string fileName) { return Path.GetFileName(fileName).Substring(0,2) + "_ImportRecord"; } private string[] GetFields(string fileName) { using (var stream = new StreamReader( File.OpenRead(fileName))) { return stream.ReadLine().Split(','); } } private IEnumerable<string> GetCsvFileNames() { var path = Host.ResolvePath(""); return Directory.GetFiles(path, "*.csv"); } #>
The template itself needs some polishing, and the generated code needs some error handling, but this was enough to prove how easy it is to spit out type definitions from a CSV header:
public class AA_ImportRecord { public AA_ImportRecord(string data) { var fields = data.Split(','); ID = fields[0]; CaseID = fields[1]; BirthDate = fields[2]; } public string ID { get; set; } public string CaseID { get; set; } public string BirthDate { get; set; } // ... }
One of the features I think will be a big hit in Visual Studio 2010 is the Extension Manager. As of Beta 2, you can find the Extension Manager under the Tools menu.
The Extension Manager allows you to download and install Visual Studio extensions from Microsoft and other 3rd parties. These extensions can include new controls and project templates for ASP.NET, Silverlight, and WPF, as well as new tools that work both inside and outside of Visual Studio. The first tool I saw when opening the Extension Manager was Gibraltar – a feature rich logging, monitoring, profiler tool recently demoed to me by eSymmetrix’s founder Jay Cincotta.
The Extension Manager is like having the Visual Studio Gallery built into Visual Studio, and saves you the hassle of going to the site, downloading a file, and double-clicking to install (the extension manager automates all this work with some help from web services exposed by the gallery). As a bonus, the manager even understands the dependencies between packages and can ensure you have everything you need for an extension to work. Some of the other extensions you’ll find on the site for 2010 include:
Visual Studio 2010 is the most extensible version of Visual Studio yet, and the Extension Manager will really highlight this fact. But, could it be even better?
Yes it could!
It’s painful to get setup with everyday development tools. It’s also frustrating to see how quickly developers on other platforms can get up and running. Package managers in general and RubyGems in particular make setup easy in an open source environment where fragmentation and spontaneity supposedly ruin a good integration story.
I realize the following scenario has some issues (like licensing issues), but in an ideal world, I’d be able to open Visual Studio and tell it I want the following:
… and so on. When I come back from lunch everything is downloaded, installed, and ready to go.
Three weeks later I might get a notification that a new ASP.NET MVC Preview is available. I’d like to punch a button in Visual Studio to pull down the latest instead of poking around on CodePlex where downloads are hard to find.
Tools like the Extension Manager and Web Platform Installer are getting us closer, but getting setup and staying up-to-date is still too big of a drain on productivity.
Seven years ago, Robin Sharp divided the lifecycle of a programming language into 7 phases:
Conception
Adoption
Acceptance
Maturation
Inefficiency
Deprecation
Decay
I think Robin is correct. Once a language becomes mainstream and reaches the “acceptance” phase, it’s only a matter of time till it becomes inefficient. This is because language designers face a dilemma:
… or …
Both directions have drawbacks.
In the former case, the language doesn’t keep up with the industry. Since the language is not “state of the art”, it only adds friction and inefficiency to the craft of building software applications.
In the latter case, the language is constantly evolving to meet the state of the art, but also collecting baggage and extra weight along the way as practices fall out of fashion. Eventually the language is so large and complex it again carries an inherent inefficiency.
Since its inception, we’ve seen the addition of generics, lambdas, and dynamic programming features to C#. These are all welcome additions for me, and make the language better.
At the same time we’ve seen the rise of new paradigms for functional and multi-threaded programming. I have to wonder if keywords like lock, volatile, and delegate are out of fashion, like skinny leather ties that only clutter up a tie rack.
Do the new features in C# 4.0, like the dynamic keyword, push the language solidly into the maturation phase? Or … after 10 years … are we passed the maturation tipping point where C# can only descend towards inefficiency?
What do you think?
Some projects use a container like StructureMap to completely replace MVC’s DefaultControllerFactory. They do by registering all controllers by name using StructureMap’s scanning feature during application startup.
ObjectFactory.Initialize(x => x.Scan(s => { s.AssembliesFromPath("bin"); s.AddAllTypesOf<IController>() .NameBy(type => type.Name.Replace("Controller", "")); }));
A simple controller factory to make this work would look like this:
public class SimpleControllerFactory : IControllerFactory { public IController CreateController( RequestContext requestContext, string controllerName) { return ObjectFactory.GetNamedInstance <IController>(controllerName); } // ... }
As I mentioned in a previous post, using Areas in MVC 2 means you have the potential for multiple controllers with the same name. A Home controller in the parent project, and a Home controller in each sub-project, for example. Now the simple approach we are using in the code above breaks down. We could do some work to make sure we are registering and looking up types using the proper namespaces, but the logic to look at the namespace constraints is already embedded in MVC’s DefaultControllerFactory.
An easier approach is to use the DefaultControllerFactory to lookup controller types and only use StructureMap to instantiate the controller and resolve dependencies. Doing so means we don’t need to scan any assemblies. StructureMap (and most IoC frameworks) are capable of instantiating an unregistered type as long as the type is concrete. All we need to do is derive from DefaultControllerFactory and override the GetControllerInstance method.
public class BetterControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance( RequestContext requestContext, Type controllerType) { IController result = null; if (controllerType != null) { result = ObjectFactory.GetInstance(controllerType) as IController; } return result; } }
Moral of the story: Don’t automatically throw away the DefaultControllerFactory. You may find it has some conventions you can make use of!