I'm currently upgrading Code Camp Server to Preview 4, and I thought it might be useful to some to see how to go about managing a (somewhat) volatile upgrade to a project.
Step 1: Create a branch for your work
You don't want these changes to break the build or anyone else's pending changes. Often times in a long, complicated upgrade there will be many parts that need fixing and you can't do it in one sitting. Creating a branch for your changes isolates you from the trunk.
First this to do is make sure your local working copy is up to date and has no pending changes. I created a branch called mvcpreview4upgrade and switched my working copy to that branch.
Now we're free to make some breaking changes.
Step 2: Upgrade the binaries to the new version of the framework
In Code Camp Server, all external dependencies are placed in the bin folder:
All of the projects get their references from here. We will definitely have to update MVCContrib to their latest once it is upgraded to Preview 4. I'll leave this to last.
Step 3: Get it compiling
Normally I'd suggest the command line NAnt build because it will run all the tests, but I'm fully expecting compile errors and I want to be able to double click on them and navigate directly to it.
Here are the issues I notice immediately:
- ComponentController has been removed completely. This hasn't been updated in a long while and we kind of expected this to happen. Unfortunately we had 2 components that used this, so we have to re-implement them using another mechanism (I think I see one already, but I need to investigate more).
- TempDataDictionary now has a default constructor, so we don't have to create a fake http context to build it. Finally!
That seems to be it, I fixed these issues and it compiles. Now to run the NAnt build (with all tests).
Step 4: Get the tests passing
Note to self: need to upgrade all the old mocking syntax to the new RhinoMocks syntax.
We can see that a unit test is failing (and we can also see a couple tests that I'm ignoring for now because ComponentController was removed).
Since the FlashMessageComponent needs to be changed anyway, I'll just ignore this test for now until we can finish the upgrade.
Another test was failing in the IntegrationTests assembly which was fixed by deleting this line:
This test is used to make sure that we can build all controllers (with dependencies) at runtime.
After fixing this we are now all passing!
Now it's time to take a look at the changed features...
Step 5: Implement the new changes
Browsing the readme that is included with the release, we can see some changes in the following areas:
- New Membership
- not sure if we want to take advantage of this since we've already implemented it
- Routes
- They are now namespaced to avoid issues with reflecting over the entire assembly
- AuthorizationFilter
- I can remove the custom one we have
- ErrorHandling Filter
- We were going to end up using [Rescue] from MVCContrib, but now I think we can use this
- OutputCache Filter
- This will be better used once we have the functionality completed and we know where the best places to implement caching will be
- Ajax
- These look like ASP.NET Ajax improvements. Not sure if they'll apply to us since we use jquery.
- ActionInvoker
- GetFiltersForAction method
- We can probably better test the integration of custom action filters with this
- ViewData
- Eval - we'll probably just stick to ViewDataExtensions from MVCContrib for strong typing
- ComponentController has been removed in favor on a RenderAction method on the view
- this means we can probably replace the sponsorcomponent controller with a standard Controller implementation
Updating routes:
I removed another remnant of ComponentController (looks like this came from MVCContrib). I also added the new namespace reference here.
For authorization we had previously created 2 attributes, [AdminOnly], and [RequireLogin]. RequireLogin will be replaced with the new [Authorize] attribute, however our AdminOnly attribute works a little differently, so some more work will be needed to get this to work with just a role name.
Our implementation won't be complete until we get MVCContrib integrated, so that'll have to wait. But for now we're at a good place to commit our work!
Why go through all this pain?
Upgrading projects to frequently released dependencies can be a pain, but I think it's a small price to pay for the constant flow of improvements we're getting from ASP.NET MVC releases. When the framework settles a bit more these updates will be mostly topical... meaning they won't sweep the carpet out from under your feet.