DerekMorrison

On software engineering, .NET, and technology

Converting An ASP.NET Web Forms Project To ASP.NET MVC

Continuing with my last post about the differences between Web Site projects and Web Application projects in ASP.NET, this post details how I converted a legacy ASP.NET Web Site project to an ASP.NET MVC project (a variant of a Web Application project).

Getting Started… ASP.NET MVC?

I originally intended to only convert the project to a web application. I ran into a couple scenarios during development in which I wanted the capabilities that a Web Application project offers over a Web Site. See my previous post for some of these differences.

However, when I started looking into the conversion process, I decided to jump ahead and convert to the ASP.NET MVC framework.

Why jump to ASP.NET MVC? I had been keeping an eye on the development of the ASP.NET team’s MVC framework (an alternative to the existing ASP.NET Web Forms model) and liked the direction it was headed. I had experimented with Ruby on Rails (probably the most well-known web MVC framework), and liked the clean separation of concerns, more natural model of web development (as opposed to the leaky abstractions of ASP.NET Web Forms), etc.

I knew it wasn’t realistic to convert all pages in the existing project to new MVC ones. However, since it’s possible to run regular Web Forms inside of MVC projects, this seemed like a good compromise to preserve legacy code while using the MVC paradigm for future work. The MVC project type is a specialized version of a Web Application Project, and current Web Forms page, even in an MVC project, can still be processed as usual since the underlying ASP.NET engine is the same for Web Forms and MVC applications.

Steps and Caveats

I began by installing the ASP.NET MVC installer, which installs the MVC library DLLs into the GAC as well as the ASP.NET MVC Visual Studio project types and templates, and creating a new ASP.NET MVC project. I then started copying files from the old to the new project.

There's a decent walkthrough here (the guide is for Web Application projects, but it was close to what I needed). Still, I was greeted with over 5,000 build errors after following the official directions and trying to build the project for the first time. I found I needed to take things slower and at a more granular level, transferring a few files at a time to the new project and evaluating the differences one by one.

I transferred several settings from the web site’s web.config appSettings section to settings in the Visual Studio project settings file (right click on project –> Properties –> Settings). This more closely follows the standard way of managing settings using Visual Studio project files, and also performs code generation to create strongly-typed properties automatically. These settings are still stored in the web.config file (so they can be changed while the web application is running), but they’re stored under a slightly different schema for project file properties.

The mechanisms for references to web services is different in Web Application projects versus Web Sites, but this is fairly straightforward as I just re-added all my references (although this might take time if you have many references).

I love ReSharper, but I had to shush it during the conversion process to avoid being nagged to death by premature warnings and code analysis.

Something to keep in mind is that the automatically generated designer files for Web Application project aspx pages are automatically re-generated when aspx files are saved. This means that when you adjust the namespace in the aspx file (e.g. with an Inherits="C4IFACT.App.WebForms.ExecutionPlans" attribute on the Page directive) then it is reflected in the designer file. I was getting many perturbing error messages about incorrect namespaces that were resolved by this (since the aspx page and designer files can temporarily get out of sync at times).

While there is some level of security from static typing and having your project "compiled" into a DLL, you should remember that an ASP.NET project has a DLL for all of the plain C# code supporting the application, but the aspx pages are not compiled when a project is built, but instead reference types in the project’s assembly and are executed by the ASP.NET runtime when a page is visited. This means that you might still have compile errors in aspx files that won’t be reflected in the build. To help this, you can flip a switch on your MVC project to trigger the ASP.NET compiler to compile ASP.NET markup and code inside aspx pages on project compile (see here for directions on doing this – it even works against Web Forms pages if you have some mixed in with your MVC project). However, this affects the performance of building the MVC project significantly.

Organization and Folder Structure

While trying to respect the default conventions of ASP.NET MVC, I also looked at Rob Conery's enhanced version and also the Rails folder structure.

While creating my folder structure, I thought about re-structuring parts of the old app and creating clean namespaces. I settled on this:

MVC Folder Structure

  • The App folder contains most executable content (following the Rails convention). MVC controllers and views are here.
  • The App\Helpers folder contains former App_Code files and miscellaneous utility classes.
  • I have a separate project in the solution containing data access code and models, so I don’t have a strict folder for models. However, I have a ViewModels folder, where model classes tailored specifically for presenting view logic or data binding are.
  • Master Pages and User Controls (Partials) are under Views\Shared.
  • I wanted to put my Web Forms into the Views folder (even though they aren't true Views), but there seems to be a hard setting in ASP routing that doesn't serve anything from the Views folder, so I placed them into a separate WebForms folder. I could have also routed Web Forms pages to friendler URLs (using the routing portion of the MVC framework), but for now I kept things simple and used the physical location (e.g. “MyPage.aspx” is accessed at “www.mysite.com/app/webforms/mypage.aspx”).
  • The Assemblies folder contains third-party, referenced assemblies (those not contained in the GAC). Note that things under here should be referenced in the project, but should also be set to Content and not be copied to the project's build output location so that they won't be included with the project output as content (although they will be included as necessary along with the project's built DLL in the published folder).
  • The Public contains static content divided into Images, Stylesheets, and JavaScripts folders.

CodeFile Versus CodeBehind

One last point - Web Site project "CodeFile" directives should be "CodeBehind" in Web Application / MVC projects. I found a great tip in the comments from this post about possible confusion that can result when converting from Web Site to Web Application projects. Here's an excerpt from the comment:

The issue with CodeFile is that the code is compiled into its own (or directory level assembly) and so the type may not be available to another page unless the control is @Registered. If you dynamically load you pretty much can't reference the ASCX codebehind class. With WAP everything goes into a single assembly so you can reference the codebehind class from just about anywhere... The thing is that if you forget to set the proper format for WAP code the page/control will still work because ASP.NET internally doesn't care whether a project is stock or WAP so the page/control runs just fine with CodeFile.
This hit upon a frustrating problem I ran into: my user controls were being compiled into their own separate assembly because I left them using the CodeFile attribute, so when I tried to import the user control (with its custom server tag) globally via the web.config (as this tip suggests) and I just referred to what I thought was the correct namespace I had problems because the user control was being compiled automagically into a separate assembly where CodeFiles are compiled.

The "Convert to Web Application" context menu for aspx pages is supposed to handle this for you and change CodeFile directives to CodeBehind, but I had issues with several pages where this didn't work and I didn't realize it for awhile. Even still, this action doesn't handle namespaces for you and still accepts the Web Site-style "Folder1_Folder2_ClassName" unique name approach instead of conventional .Net class library "Folder1.Folder2.ClassName" namespaces (how I preferred things). Basically, adjusting namespaces properly ending up involving a lot of manual work, as simply copying files and clicking "Convert to Web Application" doesn't adjust namespaces properly even if you put the files in the conventional folders.

ASP.NET Web “Sites” Versus Web “Applications”

There are, confusingly, two basic types of Visual Studio projects for developing web apps with ASP.NET: Web Sites (File –> New –> Web Site), and Web Applications (File –> New –> Project –> Web Application). I recently converted a legacy Web Site to a Web Application (and actually, to an ASP.NET MVC Web Application – there’ll be more on the conversion to the MVC framework in the next post), and ran up against several differences between the two during the process. First, a little history…

Lineage

Visual Studio .NET 2002 and 2003 both shipped with versions of ASP.NET projects that were of the Web Application variety: ASP.NET web apps were housed in Visual Studio projects similar to other project types (such as Windows Forms apps or class libraries). Upon each change, the project had to be rebuilt for the resulting web application to reflect changes. This was an unnatural model for web developers used to simple HTML or dynamic languages such as PHP and Perl (where you have a running site, make a change to some code, then simply refresh a page and have changes appear).

In Visual Studio 2005, a new default type of ASP.NET project called Web Sites was introduced. This, through behind the scenes magic, allowed ASP.NET web apps to be created that were simply loose directories with code and aspx files (there was no Visual Studio project file that everything had to be associated with) that could be loosely edited and would be compiled at first page hit and dynamically refreshed as changes were made to the running web site. This followed a seemingly more natural model for web development, but got further away from normal model of application development with Visual Studio. There was some backlash from the community, and an add-on was later released for VS 2005 that allowed developers to use the older Web Application project type.

When Visual Studio 2008 was released, it supported both the Web Site and Web Application models out of the box, developers being able to choose the style they preferred (although I doubt if this choice was a clear one for most developers).

Until recently, both of these project types used the ASP.NET WebForms model. However, with the recent 1.0 release of the ASP.NET MVC Framework, there is yet another way to do ASP.NET (although, basically, MVC projects are Web Application projects).

Differences

Why did I do the conversion? Because, for my specific case, the features of the Web Application model better suited my project than those of the Web Site model.

Here is a list of the major differences I came up against:

  • Web Applications can properly use conditional compilation constants (having them change based on build configurations).
  • References are more tightly controlled with Web Applications (like normal VS projects). With web sites, it's a little indirect. Assemblies can be added to the Bin folder where they're automatically referenced by the site, or they can be referenced in the web.config file (for assemblies stored globally on a computer in the GAC).
  • Since Web Application project files are proper MSBuild files, build actions can be done (pre- and post-build, etc).
  • With Web Applications, namespaces can be more properly managed. With Web Sites, all compiled class code (not code behind files directly paired with a page), must be stored in a special "App_Code" folder. So, following the convention of storing classes in folders corresponding to their namespaces, these would have to be under an "App_Code.Blah..." namespace).
  • Pages in web applications must have a "designer" file associated with them (e.g. “MyPage.aspx.designer.cs” for a C# web app). This is a partial class where the server controls in ASP.NET markup are declared in auto-generated code (all ASP server controls correspond to .NET objects). Here are Scott Guthrie's comments from his good walk-through (Rick Strahl also has a good description here and a re-visit to it here):
    • “One difference between a VS 2005 Web Site Project and a VS 2005 Web Application Project is that the VS 2005 Web Site Project Model dynamically generates the tool-generated partial class half of a page, and does not persist it on disk. The VS 2005 Web Application Project model on the other-hand does save this partial class on disk within files that have a .designer.cs extension and compiles it using the in-memory VS compilers when a build occurs (one benefit of this is faster build times).“
  • A strongly-typed profile object is automatically generated with the Web Site project type, but requires a special add-in to Visual Studio when using web applications (available here) for some reason. Alternatively, you can not use the strongly typed object and get values dynamically at runtime with magic strings.
  • Web Site project "CodeFile" directives are "CodeBehind" in Web Application projects. These directives control how aspx pages are compiled. The CodeFile directive can still be used in Web Application projects, but are not compiled correctly. There’s a great tip in the comments on this post about possible confusion that can result when converting from a Web Site to Web Application project. Here's an excerpt from the comment:
    • “The issue with CodeFile is that the code is compiled into its own (or directory level assembly) and so the type may not be available to another page unless the control is @Registered. If you dynamically load you pretty much can't reference the ASCX codebehind class. With WAP everything goes into a single assembly so you can reference the codebehind class from just about anywhere... The thing is that if you forget to set the proper format for WAP code the page/control will still work because ASP.NET internally doesn't care whether a project is stock or WAP so the page/control runs just fine with CodeFile.”
  • Web Applications have a strongly-typed app settings section in the web.config corresponding (and automatically updating with code-gen) to the Visual Studio Project settings.
  • When you compile a Web Application, it compiles the code behind files so that if a change is made to a running web app's code behind file it must be re-compiled (however, if you make a change to the aspx file of even a Web Application, then it still auto updates with an explicit re-compile – honestly, I'm confused about this part). With a Web Site, however, it will detect the change and re-compile no matter what.
  • You must recompile a Web Application almost each time you make changes to it. This sounds worse than it is. The build is generally fast for me, as Visual Studio does a good job of keeping track of what has already been built and what really needs to be rebuilt. Also, you can "build" a Web Site project type from within Visual Studio, but really this is only doing a dry run of the build to catch possible compilation errors in the manner that the ASP.NET runtime does when a Web Site is visited.

JavaScript Coding Guidelines for ASP.NET

Recently for work as part of our sporadic push to create coding standards, I contributed by writing a draft of our JavaScript coding guidelines document. I've probably been the most active developer at work JavaScript and Ajax, and this combined with me having recently finished Douglas Crockford's excellent Javascript: The Good Parts book made me the most likely candidate to do so. Here is what I came up with.

The document is written from an ASP.NET developer's perspective, and since the direction for JavaScript that Microsoft is pushing now is a mix of its own ASP.NET Ajax library and jQuery, those are the libraries I focused on. Also, I didn't write much into strict coding standards per se (i.e. variables should be named and cased this and this way...), but instead focused on general guidance for the JavaScript language and some key best practices.

Here are several resources I used to come up with the standards (these are also in the references section at the end of the document):

Four Rules

...for software project management. I heard these on a recent episode of .NET Rocks titled "Pat Hynds On Why Projects Fail" (skip to around the 13:00 minute mark - are the intros long enough on this show or what??).

  1. Status - if you're not paranoid earlier, you're going to be unhappy later.
  2. Never Assume - always make sure requirements are clear between you and the customer.
  3. Don't Be Wishful - a project is not done until after the coding is done and lots of other things happen. When asked if a project is done, you should be able to definitively say "Yes" or "No" (without any "Yes... but...." responses). You must confirm with the customer that the project is done.
  4. No Spec, No Estimate - many people want a fixed-bid price when they give a time and materials spec. Make sure that a detailed spec is given by the client. Include what will not be done.

 

Using Ruby and Rake with ASP.NET

For awhile now at work, I've been using a loose collection of PowerShell scripts and manual steps to handle deployment of ASP.NET sites and associated SQL Server databases. I recently switched to using a Rake build script to not only automate deployment, but also to help in a few other tasks such as re-building the development database, and synchronizing the staging database with the production db.

Briefly, Rake is a Ruby version of Make, and is a framework for build scripts written in Ruby. Since a Rakefile (the main build file you work with) uses a plain Ruby syntax (albeit one that uses a few Rake conventions), it's very easy to get up to speed with if you know a little Ruby, and even if you don't, Ruby's syntax has a reputation for being fairly straightforward anyway. Rake also has many built-in library functions for handling builds and uses a dependency-based computational model. For example, I can specify that task A depends on task B and be sure that task B is always called before task A:

task :a => :b do
     puts "World" 
end 
task :b do
    puts "Hello " 
end

Rake is normally used in the Ruby world (such as for working with Ruby on Rails sites), but is generic enough to be usable with other setups such as .NET. Why did I switch to Rake? I tried, I really tried to like and use PowerShell. PowerShell is Microsoft's newer command line environment and scripting language. It's a definite improvement over the normal Windows command prompt, as it offers a greatly enhanced command set and direct interoperability with the .NET framework. PowerShell, as well as a light development environment for PowerShell scripts, are tentatively set to be included in Windows 7.

However, I was put off by PowerShell's syntax, which uses a blend of curly braces, mixed case keywords, dollar signs,  and unconventional operators e.g. the less than or equal to operator in:

for ( $i = 7; $i -le 84; $i+=7 ) { $i }

Also, since PowerShell is relatively new, there seems to be poor support for it. Editing support is not included with Visual Studio and it's not natively supported (with syntax highlighting, etc) in common free text editors such as Notepad++. Also, while you can write individual PowerShell scripts and tie them together yourself, there's not a robust framework such as Rake made specifically for builds (although there is the psake upstart). Ruby and Rake, on the other hand, are much more mature and established.


To deploy, the central steps that my Rakefile does are:

  1. Take in an argument specifying whether to target the staging or production server.
  2. Deploy the database
    1. If deploying to the staging server, synchronize the schema from the production server (using RedGate's excellent schema comparison and synchronization tool).
    2. If deploying to the staging server, synchronize the data from the production server (using another RedGate tool). This and the step before insures that the staging server has a db that's a mirror of production.
    3. Run migrations to get the db up to the latest version.
  3. Deploy the site
    1. Compile the Visual Studio web site solution.
    2. Copy the site files to the staging or production server (using the free Robycopy tool).

I should run the unit tests as a part of the deployment task, but since the project is fairly small, I've been running them independently before deploying. I have a task set up for the unit tests, so I could fairly easily plug this in later.

There's a task that recreates the test database on a developer's local system, and it actually still calls out to an older PowerShell script that I haven't bothered converting yet (but having Rake and PowerShell interact is fairly seamless at the moment).

Here's my Rakefile. The steps outlined above should be recognizable in the script, but please leave a comment if you have a question about anything in particular in it or any suggestions as well.

Upgrading My Home Theater PC

I recently turned on the TV to see my home theater PC frozen and a nasty buzzing sound coming from the speakers. Long story short, eventually I figured that my motherboard had gone bad (and not surprisingly too, as the system was my old main computer that I built almost 6 years ago and had an AMD Athlon XP single-core processor, etc). I can’t say I wasn’t expecting this sometime.

The skeleton of the system is still fairly modern, and the case looks good in the living room alongside the receiver, so I figured I could try to replace the guts. Since this computer is mainly used for playing video from a shared media folder or streamed from the web, I didn't need the most up-to-date hardware, and I wanted to find a motherboard with a lot of capabilities onboard that was fairly inexpensive. Additionally, I wanted the system to be quiet and low-power, as the old system, while not terribly annoying, was a little louder than most electronics you find in a living room.

Luckily for me, Coding Horror had a great piece on building something very similar to what I wanted that was posted last April. The hardware I went with was slightly updated from what Jeff used, but essentially the same:

CPU AMD Athlon X2 4850e 2.5GHz Dual Core (45w) $60
Motherboard GIGABYTE GA-MA78GPM-DS2H $100
RAM 2 x 1 GB Mushkin DDR2 800 Mhz EM2-6400 $10
Blu-ray Drive LG 6X Blu-ray DVD±R DVD Burner $115

* I used my existing parts for the remainder.

The specs and reviews of the motherboard surprised me; I read it was capable of decoding Blu-ray video very smoothly with its miniscule (by today’s standards) 128 MB of on-board video memory. This being said, and even though bare Blu-ray drives are numerous, they’ve come down in price, and Netflix has a growing catalog of Blu-ray discs, I still think getting a Blu-ray drive may have been unnecessary, but I caved in to the appeal of the bright and shiny.

20090131-185830-IMGP2757

Ports!

Also, the processor is a fairly powerful dual-core one yet only uses 45W of power. Given this, the stock heat-sink and fan that’s included with the processor is supposed to suffice while being fairly quiet. The CPU’s fan speeds up as the processor temperature rises, and in my testing I never heard it kick into a higher gear.

20090207-130342-IMGP2759

Putting it all together in the Antec HTPC case

Resolution

The biggest problem I ran into was getting the proper resolution driven to the TV. The TV (a 46” Sony LCD), is capable of displaying up to 1920x1080 (1080p), and my old system would show this resolution in Windows for me to select. For some reason, the new system and video card would only let me select up to 1600x1200 using a VGA cable, and, after experimenting with different drivers, an HDMI cable (which would display the desired resolution but looked fuzzy), and ATI’s Catalyst display software, I eventually settled on using PowerStrip to force 1920x1080 through the VGA cable. The results are good, and the picture is comparable in sharpness to a computer monitor.

Testing

I tested playing several HD 1080p sample videos with good results. In informal testing, overall CPU utilization stayed around 40-50% when playing full screen 1920x1080 video.

I added Blu-ray access to my Netflix account (for an additional $1), and got my first Blu-ray disc in today (Burn After Reading). I needed to use PowerDVD to play the film (included with the drive), but the video was beautifully smooth.

20090212-195856-IMGP2766

The finished setup (receiver on the left, PC on the right)

Windows 7 and Windows Media Center

I also did all of this testing using Windows 7 Beta 64-bit edition, and I didn’t experience any major stumbling blocks. Where applicable, I chose the Vista 64 version of software, and only encountered a few glitches (such as preferences not taking effect immediately or general UI bugs).

Windows 7 Beta Ultimate edition includes Windows Media Center, and I tested using it to access shared video on my home network and some internet TV “channels” that are set up by default in the app, but since I don’t have cable TV and and don’t use Windows Media Center as a Tivo, I could manage (as I’ve been doing), by picking shared network video files from Windows explorer or by watching content on ABC.com, Hulu, etc.

Boxee

I also tried the alpha version of Boxee for Windows, but the display was distorted badly when the program started and it was unusable (driver? Windows 7 incompatibility?). I’ll have to see if there’s a workaround for this and look out for a beta version of it.

Back To School

I was a little put off by the last graduate class on formal methods that I took a little over a year ago. I got frustrated, and decided to quit with the idea that I would pursue a focused, independent course of study relevant to my career (meaning I would experiment with and study new technologies in my spare time). I know what’s better for me than the out of touch instructors at a university, right?

Last week, I started a class at Auburn again (towards a Master of Software Engineering degree). A couple reasons come to mind:

  • I don’t have the discipline to direct myself on any outside of work study that’s remotely close to the level of work that is required of you from a university course. It’s far too easy for me to just spend an hour going through my RSS reader on development blogs and call that learning than it is for me to struggle with working on something in depth in my spare time. I hope I can get better at this someday.
  • I’m over half-way through my master’s degree course requirements, and it would be nice to complete it.
  • Although I don’t get a feeling that master’s degrees are a necessity for even advanced software engineering positions, I still think the degree will help me in my career.
  • Work can be monotonous, and it would be good to get my neurons firing in different ways.

You can make up seemingly reasonable excuses about why you shouldn't do something challenging, but even if that something is not 100% on target or good for you, if it's in some part beneficial, then when you look back at it you're probably not going to regret it.

My current class is on web development using Java Server Pages. While JSP is by far not the hippest buzzword in the web development world, I’m still excited about learning something different.

iPhone Duel - Evernote Vs Notes

About a week after switching from the stock iPhone Notes app to Evernote, I'm moving back to Notes.

The feature list for Evernote is seemingly impressive. You can enter notes on their site, from a Windows or Mac desktop application, from email, or from a Windows Mobile or iPhone application. Content is stored on Evernote's servers and synchronized with all your devices. As the intro video on their site shows, you can highlight content on web pages and use the desktop client to easily send something to your Evernote account. Using the iPhone client, I was given the option of creating notes by entering text, taking a picture with the phone's camera, or even by capturing a voice message.

For me, however, the way I mainly want to use it is to simply jot down something fairly short when an idea hits me so that I can later go through my notes and process it. I can do the same with the phone's built-in camera and photo management app, and I already use Jott for capturing and transcribing voice notes.

Still, I decided to try something more advanced than the stock notes app and give Evernote a whirl.

I can really understand this Daring Fireball post on iPhone-Likeness now (scroll down to where the Notes app is discussed). It's as if the Evernote iPhone app is trying to be too clever, and in doing so, fails at following iPhone UI conventions and loses the simplicity that made using the Notes app useful. There were just too many fields and too many tabs to fidget with, and I felt the app was getting in the way of writing my thoughts down. The Notes app, by comparison, is beautifully designed and fun to work with (important for an app that you're going to be using on a regular basis).

Also, Evernote's syncing service was ok, but there was misleading lag at times (I lost a couple of notes when I accidentally shut down the app before it had a chance to save and sync notes, and unsynchronized content would appear momentarily before changing), and I like the simple mental model of having things be in one place that I can depend on. And, after going through years of duplicated or missing contacts and calendar events using Outlook, Exchange, and even a trial of MobileMe, I'm still nervous about syncing.

For sure there are some perceived cons to Notes: there's no cut and paste (the same for all iPhone apps), notes can only be sorted one way, the "loading" screen is misleading and annoying, and there's no dedicated way of syncing notes to your desktop. But actually, these haven't bothered me and, for the way I use it, there are adequate workarounds. It's hard to believe, but I honestly don't miss having cut and paste, the sorting I just deal with, and if I have a long enough note that I want to get out of the phone, I can just email it to myself (but maybe these are symptoms of Apple Stockholm syndrome).

But that's probably enough time devoted to a little note-taking app for now...

A Problem Unit Testing with .NET Private Accessors

Recently I ran into a problem using .NET accessor methods to unit test private methods. I was able to resolve the problem, but in doing so ended up abandoning accessor methods in favor of a simpler approach (using reflection).

But should you even test private methods?

It's a nuanced question. On one hand, it seems reasonable to break a class into small, purposeful private methods (exposing the main points of the class publicly) but still test the smallest possible chunks of functionality by testing those private methods in addition to the public ones. On the other, testing only public methods should exercise those private methods enough, and testing private methods can make your test code more brittle to change. There's a good table here with more arguing points.

For my purposes, I decided that I should.

What's a private accessor method?

But how do you get at privates? The default .NET unit test suite (MSTest) provides a seemingly handy facility within Visual Studio to easily do this by generating so called "private accessors". 

Just right click on a private method in your code like so

then click "Create Private Accessor" and point it to a project containing your test code. and the tool magically provides proxy types (with the suffix "_Accessor") that expose these private methods publicly and that you can use from within your unit tests to access these private members like this:

var myObject = new MyClass_Accessor();
var result = myObject.PrivateMethod();

How useful, right?

A problem

I ran into trouble when I had a private method that returned a generic list of private classes. When I generated an accessor for the method, an accessor for the private class was also generated so that the accessor method actually returned a list of "MyPrivateClass_Accessor" types instead of "MyPrivateClass" types.

This generated code actually gives an error, and seems to be a bug in Visual Studio 2008. MyPrivateClass_Accessor derives from MyPrivateClass, and while you can cast a derived class to its base class, in .NET you can't cast a list of derived classes to a list of its base classes (as I assume it's doing internally in the generated code).

I suppose they're working to fix this.

A simpler alternative

Using a bit of code (good samples are available here and here) that uses reflection and extension methods, you can still fairly easily test these methods like so:

var myObject = new MyClass();
var result = (List<MyPrivateClass>) myObject.CallMethod("PrivateMethod");

Sure, there's extra casting work and you have to use nasty string literals for the method names, but this is test code after all, and if it breaks you should know quickly from a regular test run.

A lesson

One of the hazards, it seems, working with Microsoft tools is the strong focus on tooling itself. This can sometimes get in the way of more elegant solutions based on simpler principles.

Not that all or most of the tools are bad (a lot of them I feel make me more productive), but it's a glamorous trap that you should be aware of.

DevLink Conference - Day 2 Notes

devLink2008Sponsors

The session that made the biggest impression on me from Day 2 was an informal, impromptu talk that was arranged during lunch to demonstrate Test Driven Development (TDD). The premise was that several presenters or prominent developers from the conference were to start a simple, greenfield sample project and use TDD to write code from requirements.

The results were striking (and not in a good way).

The leaders took suggestions from the audience about what kind of app should be developed and simple requirements were gathered. As several volunteer developers took turns typing, there were arguments over difficulties with the environment, over naming guidelines, over Visual Studio add-ins, over testing frameworks, and over code templates. Some of the typists experienced with TDD jumped ahead of the general audience, writing code that they were accustomed to writing without properly explaining themselves. There were arguments from the audience that some of the code was being written without first writing tests and therefore was in violation of TDD.

All in all, it was eye opening for me (having little experience with Test Driven Development) to see several proponents of TDD fall apart in this simple demonstration.

Of course it was not a properly prepared talk. It did not have a focused vision, and there was a lot of informal distracting chatter between the audience and the group of people directing the talk. However, it was still discouraging to be denied the chance of seeing a cohesive demonstration of a practice I've heard quite a lot about.


Day 2

Web Testing

McWherther

  • TestDriven.Net
  • MbUnit row tests (like data driven tests in MSTest).
  • The very precise .NET Stopwatch class used to performance test (dataset loading, etc).
  • Test for 0, 1... N. If things work with 0 and 1, and some N, then they should work for other values (but watch out for large values).
  • May need to run integration, web, slower tests at night because you want tests to run very quickly.
  • Even if your unit tests are hitting the db, that's still ok and at least you're doing testing.
  • Don't show me pictures of and talk about your dog - I don't care.
  • Very expensive. Visual Studio Team System (AKA "Left Kidney") Edition is $5000 for single developer.
  • Web tests, recorder tool
  • Load testing. Mercury tool, other load testing tools?
  • Test 56k connections for time outs, don't assume everyone has broadband.
  • Fiddler. Using to inspect payloads.
  • FireBug has some performance measuring tools, but it's not as comprehensive as Fiddler.
  • Watin (Ruby' Watir for .Net).
  • Watin test recorder. Updates fixed Ajax issues.
  • Setting up Cassini for testing.
  • Wcat (in resource kit for iis 6).
  • Go command line. It'll be cheaper and more powerful.
  • Profiling. Ants profiler.
  • Web testing, load testing, profiling. Understanding these things seems to be concentrated on more maybe, but there could even be more sessions done with it.
  • DotTrace.
  • It's good hearing about the various tools, but doesn't seem to be enough real-world experience behind it.
  • TDD by example, Kent Beck
  • Pragmatic Unit Test with C# and NUnit
  • Behavior Driven Development talk: Tinyurl.com/Mx4p2
  • They keep saying to sneak practices into organizations, as if managers will suddenly notice that code is better and ask "Wow, things are great! What did you change?".
  • I'm getting fatigue from youthful enthusiasm.
  • SiteWalker.

Open Spaces - SOA

  • Kickoff, how to get enterprise to adopt SOA from existing communications code in place
  • Flex doesn't work well with SOAP, so Rest is a better fit?
  • Using SOA to tie disparite systems together.
  • What is SOA is a bad quesstion. More appropriately, what do you want from it. What does your company want from it.
  • It can be soap, rest, remoting. Whatever can work.
  • It's message passing. To create a big interface that will bridge large #s of gaps is not good to focus on.
  • Soa is very ambiguous I'm feeling. It's people dealing with interconnected systems.
  • It's a buzzword that non-technical people in companies can latch onto.
  • Woa - web oriented arch
  • Cloud computing sounds great, but we're still probably far away from having companies trust it.
  • Excel being able to pull data is impressive to business people. They could get this ,it's hard to grasp sharePoint, bam, sitefinity.
  • It's better to show than to tell about.
  • Bof
  • "I ducking hate sharepoint"
  • You can't put Esb in a box
  • Something that maintains a directory of services is valuable
  • Uddi
  • Couple of consultants expressing experience integrating services within companies.
  • Oslo? Does uddi fall away with it?
  • Msft has a roadmap, kinda private, and if they stop talking about something then maybe it's going away.
  • Thomas Erl books. Great resource, big books, but a quick read.
  • New patterns. Maybe driven by ego. But the value of a pattern is that it capitalizes on existing knowledge and experiences.
  • Scott Bellware is becoming House MD
  • Soa in a word
    • Reusability? been promised before
    • Reusability within the enterprise
    • Interop maybe?
    • Integration?
    • Loosely coupled integration?
  • We're not doing anything new, you could still just pass a flat file around, but this is a more open way where you maybe don't have to understand an opaque util that processes that flat file.
  • Noticed that laptops, slides didn't look near as refined and beautiful.
  • Soa has a steeper learning curve because you need to know about several pieces.
  • This is going to be a factor for me layer (integration), so should increase priority of Astoria, restful stuff ... Also, design patterns.
  • It's important to separate components where they can be service oriented.
  • With speaking and writing, even general conversation, explaining ideas elegantly is the key skill. I need to be able to think  clearly, and restrain myself. Can practice this is writing. Keep myself honest by proving my points. I don't think quickly though, so slow down to go  fast.
  • Open spaces help to flesh out ideas from various people. The speaker has to be very, very good to attend a strictly face-forward presentation.

Lunch - TDD demo

  • Start using TDD syntax for tests. Stop always calling things BlahTest.
  • Take out template code and comments (it's noise).
  • Lunch session on TDD was full. Seems to be interest in testing and tdd. Even though we're using statixally types languages, we still need tests (and it's a tool to develop business requirements)
  • Try doing TDD on a refactoring or new feature. Let the design drive me.
  • Was great to see speakers being engaged. Lots of stumbling, arguments over tooling. Good to see them in practice.
  • Are getters and setters evil?
  • The zealots have an aversion to MSTest.
  • Class WhenAllPeopleAreFed
  • Method Are_there_people_to_feed, for example.
  • It take discipline to take small steps and not skipping things.
  • Michael Feathers book was highly recommended.

Service Design

Rayburn

  • Best is the enemy of good. Good enough is by def good enough.
  • Soa is nothing but evolution.
  • Quotes a study that documents the most popular real world benefit of implementing SOA is agility.
  • YAGNI
  • You can't get it right.
  • WF and WCF go together well and Msft will continue to support them. It's a good idea to invest learning in these.
  • WSDL plus address
  • Are open spaces for people who like to talk. Is it more ego driven?
  • It's not RESTful
  • How do WCF and REST work together
  • Use XML namespaces. Many people neglect this.
  • Service methods are not code. Take one parameter that has all parameters bundle, then can add optional parameters.
  • What doesn't matter? New operations and new properties on existing types.
  • Orgs that are just starting to use or create services shouldn't need an ESB. Don't get treatment until you feel pain.
  • How will Astoria change this stuff? I haven't looked at it a lot, but I don't see this as the major problem.
  • Some asks, what if I need to return a million rows? If it's possible and you have enough bandwidth and power, do it. Or consider using an async technique, such as a return address (if doing programmatically) or provide an FTP address, username, and pass that a file will be present at.
  • Oslo.

Closing Keynote

Joe Stagner

  • Today's problems can't be solved with the same thinking that got us into those problems. Einstein.
  • The web is completely broken? No!!
  • Consumer IP traffic should surpass enterprise for the first time in 2008.
  • Last year, my parents did most of their Christmas shopping online.
  • Data centers are the fastest growing energy segment in the US.
  • This is bullshit. He's just talking with his friends in the audience and making stupid jokes. Guy next to me just said, this is awesome, which makes me depressed about the audience.
  • Develop habit of using time better. Pretending like I have less time and try to effectively work 4 days. Focus hardcore. Also, prepare this year for when I have to work in a real environment. Stricter.
  • Msft is the biggest SW company. 78k employees.
  • Question: What is Msft development division doing to reduce complexity and make adopting new techs that are rapidly being produced more palatable?
  • Answer: You don't have to do it, and Mvc
  • Although I don't think his talk was particularly innovative or inspirational, his attitude seems to generally be in the right place with regards to embracing future developments.
  • Makes a joke to not use UpdatePanel. They've apparently had bad experiences with it scaling.
  • When OSS for Msft? "Honestly, I think a lot of people don't get OSS in Msft."
  • A lot of people don't realize that Msft cannot accept legally contributions from OSS contributors. They can't take the risk. Is the risk perceived? Will Msft ever get over this? Not likely.