Mad Props!

Omniscience is just a Google-search away.

Login

You're reading Mabsterama, the weblog of Matt Hamilton. Enjoy your stay.

Oops - You can Sign In Now

So it turns out that if you want to use an existing ASP.NET membership store with Graffiti, there's one thing you need to do with your existing users - add them to the "gEveryone" role.

If you don't do that, your users will be able to sign in, but will get an "access denied" error when they redirect back to the page they came from. Not ideal.

Fortunately there's a quick and dirty way to do this, using direct SQL. And here it is!

declare @gEveryone uniqueidentifier

select @gEveryone = RoleId 
from aspnet_Roles
where RoleName = 'gEveryone' insert into aspnet_UsersInRoles (UserId, RoleId) select UserId, @gEveryone from aspnet_Users where not exists ( select 1 from aspnet_UsersInRoles ur where ur.UserId = aspnet_Users.UserId
and ur.RoleId = @gEveryone)

Technorati Claim

Nothing to see here, guys - just claiming the new URL for Mabsterama on Technorati.

Technorati Profile

Welcome to Graffiti!

I've done it! I've installed Graffiti 1.1 on Mad Props and have migrated all my posts across!

The only thing left to do is redirect incoming requests to my old blog so that they seamlessly point to my new one. For now I have disabled comments to posts on my old blog so I shouldn't have to worry about migrating any new content across.

I've already changed the feedburner feed over, so chances are that you're reading this in your RSS reader. If that's the case, come visit the site!

Internal Software Development

Late last year here at work, we managed to push through a restructure of our software development staff so that they all come under me and work as one team. When I say, "all", technically there are four coders including me, so it's not a huge team.

The reasoning behind the formation of the team is pretty simple: We don't know each other's code. When a program failed for whatever reason, it usually fell on one person to fix it, and that person had to be the guy who wrote the code. Nobody else would even know where to start looking to get the program up and running again. The situation was untenable, and this became painfully obvious when, over the course of last year, three of our developers decided to move on, leaving a lot of legacy systems behind.

So as a team, we have to collaborate. More than one person knows about any given system, so there's some redundancy built into the support of the system once it has shipped. As much as possible I'm trying to run the team as if we were a third-party contracting team - taking on a few projects at a time and seeing them through to completion, using TDD and agile methodologies (which we're learning as we go).

A lot of people have written about the differences between internal software development and commercial development. In some ways it's easier, because you can introduce dependencies on software that you know exists in the target environment. For example, you can point to a known server and don't need to allow users to configure their connection strings, or provide functionality that depends on Excel being installed. That sort of thing. However, in a lot of ways it's a lot more frustrating to be part of an internal development team, because the pressure is always on shipping quick-and-dirty code rather than polished, maintainable code. Users want things done yesterday.

I've found that with a bit of politicking it's possible to convince users that "quick and dirty" isn't the answer. Most people are quite reasonable and understand that writing maintainable ("healthful" as Scott Bellware would say) software takes time and effort, and it's well worth it. There is, however, still one big difference between commercial and internal development: The ability to turn work down.

It's a good problem to have if you're a commercial software house: Too much work. If all your guys are swamped to the point where any new projects will just have them thrashing and never completing anything, you have little choice but to turn back new clients. You knuckle down and clear out the jobs at hand and then go back to them to see if the work is still there. Perhaps you tell them when they first approach you that you're happy to take their business but won't get to it for a few months.

In an internal software development team, though, turning back work is just not an option. None of the seemingly-endless stream of middle-managers will accept that you're too busy to work on their problem. Worse still, even the most trivial of applications are number one priority to the person who asked for them, and they often have no idea what goes on beyond their desk, so the truly important projects are meaningless to them.

Over the past few weeks I've seen this attitude come to a fore, and it's getting quite stressful. We have quite a bit of work to do, but every time we feel like we're making any headway on a project, two more projects appear out of nowhere. It's like fighting a hydra.

Of course, the up side to this is that I get paid every week whether it's busy or not, along with all the benefits of full-time employment. Perhaps the stress of not being allowed to say "no" is a small price to pay.

Graffiti Progress

Two posts ago I talked about my initial experiences in getting Graffiti set up on a machine at home, co-existing with my existing Community Server installation. I'm a lot further down that path now, and almost ready to deploy to the live madprops.org server, which will at last let me move my blog back to the root folder instead of /cs/blogs/mabster subfolder.

Using Graffiti's NVelocity-based theme engine, I've managed to get it to look almost identical to the current Mabsterama theme, with a few visual improvements. Something I'm very proud of is that I've essentially rewritten the theme using much better CSS-based layout rather than table-based hacks. The site's code looks much cleaner and feels more responsive somehow.

There are only a few things left to sort out before I go live, and I'm hoping that they get resolved in the final release of Graffiti 1.1 (I'm using the beta).

The first is that Graffiti won't let me use non-alphanumeric characters (other than the hyphen) in my tags. Therefore my "C#" tag becomes "C", and my "ADO.NET" tag becomes "ADO-NET". I can live with the latter, but the former completely changes the meaning of the tag, so that's not ideal.

Secondly, the tag cloud widget in Graffiti seems to be very inaccurate compared to Community Server's. It completely excludes some very popular tags in favour of less-popular ones. I'll have to wait for this to get sorted out 'coz I loves me some tag cloud goodness.

The migration tool to pull posts in from Community Server seems to work well - it manages to pull in all 1200 or so of the posts from this blog. I'm still undecided as to whether to bring the old stuff across though. Maybe I'd be better off leaving the old content in CS and making a fresh start. What do you think? Leave me a comment.

If I do bring the old content across, the ability to redirect incoming requests for the old post URLs to the new Graffiti post would be great. I've experimented with a few tools that purport to do that for Graffiti, but because I want CS to remain enabled as an ASP.NET application they don't seem to work - CS handles the request before Graffiti can redirect it. I may have to do the redirect from CS itself, but I have no idea how just yet. Some more reading and forum-posting required.

All in all I'm really enjoying Graffiti, and I can recommend it to anyone looking for a non-commercial content engine. Bring on 1.1!

Switching to FeedBurner

Ok, so in my last post I said that I may eventually switch over to FeedBurner for my RSS feeds. Well, I've done that now. If you point your RSS reader at http://feeds.feedburner.com/mabster you'll be subscribed to this blog no matter where I put it, so change your subscription when you get a chance.

Playing with Graffiti

When madprops.org first came into being, it was a shared site owned by me and three friends. We each had a blog and aggregated them on the main page. Over the years we lost a few people to other sites, until eventually I decided to take over the site completely.

So for a while now I've been wanting to move the main part of the site from the "/cs/blogs/mabster" folder back to the root. I thought about installing Community Server 2007 in the root of the site and running it concurrently with the "/cs" installation (against the same database), but that's overkill for just my blog.

So on the weekend I took a look at Telligent's other content-management solution, Graffiti.

Graffiti basically reduces content management down to its bare essentials: Posts and categories. You define categories (which may have subcategories), then create posts against those categories. You then have the ability to view individual posts, or to list posts by category. To facilitate blogging, Graffiti also gives you RSS feeds, comments and tags against your posts.

Best of all, Graffiti has a very simple skinning and layout engine, using NVelocity for its skins and a "widget" system for its sidebar boxes. I was able to throw together a skin for Graffiti at home (on an old XP box running IIS) that looks almost identical to my Mabsterama skin in only an hour or so.

I've had a few problems with my Graffiti trial so far:

The first was that when I installed Graffiti to the root of my site, it hosed any subfolders that were running their own ASP.NET applications (like Community Server and Sourcegear Vault). After a bit of searching on Google, I discovered this post on the Community Server forums that talks about wrapping your web.config's <system.web> section in a <location> tag. As I've said in the past, I'm a total ASP.NET newbie, so this was news to me. It totally fixed that issue for me.

The next issue is around the ASP.NET shared membership provider. I've bookmarked this blog post by Dan Bartels which describes how to make Graffiti use an existing ASP.NET membership store (for example, the one used by Community Server) so your users can log into Graffiti with the existing CS usernames and passwords. I've followed all of Dan's steps, but the only user I see in my Graffiti installation is the default "admin" user, so I've missed something there. I'll post about this when I solve it.

Lastly I've seen some weird layout problems when combining certain widgets. For example, if I place the Xbox 360 Gamercard widget in my sidebar above another widget (like the Tag Cloud or Del.icio.us links widgets), all hell breaks loose and I end up with widgets in the main part of my site instead of the sidebar. I haven't worked this one out yet, so for now I'm defining the sidebar boxes manually in the theme rather than relying on built-in widgets. Less than ideal.

Once I'm satisfied with my sandbox installation of Graffiti, I'll upload it to madprops.org and start blogging there instead. Rest assured that I'll give readers plenty of time to adjust their bookmarks. I may even move to FeedBurner beforehand so that RSS feeds are seamlessly updated. Stay tuned!

WPF, IUIs and Paul Stovell

Rock-star developer Paul Stovell has just published an article about creating Inductive User-Interfaces using WPF's navigation framework. Paul's on something of a creative roll right now, having just released beta 1 of Bindable LINQ.

I've been a big fan of the IUI paradigm for a few years now, and have had a lot of success with a Windows Forms application that made use of Michael Weinhardt's framework (which he describes in this article on MSDN). Most users nowadays are very comfortable with a page-oriented application design. They understand "Back", "Forward", "Refresh" etc. It only makes sense to capitalize on that familiarity in your own apps.

Give the article a read - you'll be glad you did!

Another C# Idea: Interface Method Chaining

Let's say I have an interface with method overloads like this:

interface IFoo
{
IList<Order> GetOrdersByDate(DateTime orderDate);

IList<Order> GetOrdersByDateRange(DateTime fromDate, DateTime toDate);
}

It has two methods to get orders by date - one that gets orders for a single day, and another that gets them for a range of dates. Pretty straight forward.

Let's also assume that you want the logic for getting orders for a single date to be the same as getting them for a range of dates. When implementing the interface, you know that 99% of the time you're just going to call one method from the other, like this:

public IList<Order> GetOrdersByDate(DateTime orderDate)
{
return GetOrdersByDateRange(orderDate, orderDate);
}

I think it would be handy to be able to enforce this behaviour back in the interface, in such a way that the implementing class didn't even have to implement the method if they chose not to. You could define your interface like this:

interface IFoo
{
IList<Order> GetOrdersByDateRange(DateTime fromDate, DateTime toDate);


IList<Order> GetOrdersByDate(DateTime orderDate)
: GetOrdersByDateRange(orderDate, orderDate);
}

So now our interface is defining a default "chaining" behaviour for the single-parameter method. If you want to, you can implement that method in your class, but if you don't, it'll just call your implementation for the first method.

So it's sort of like being able to specify default values for parameters back at the interface definition. I think the constructor-chaining-style syntax is nice and understandable. What do you think?

Update: I just realised that you could achieve something very similar using an extension method on an interface to define one of the methods. That's so crazy it might work!

Some New Comicster WPF Screenshots

For those who are keeping tabs on me as I (excruciatingly slowly) rewrite Comicster using Windows Presentation Foundation, here's a fresh couple of screenshots.

First, the main window showing an issue (click to enlarge):

Comicster's Main Window 

See the "Online Details" down in the bottom right? That's a button. I need to make it a little more obvious that it's something you can click on, but when you do, it shows a panel with the details of the current item from our online database. Here's a shot of a publisher with its online details showing:

Publisher with Online Details

This hopefully also demonstrates that the central "issues" list is context sensitive - it's showing only the issues for the selected publisher.

What do you think? It's surprisingly useful as a browsing tool in its current state. I'm working on adding and editing items in the collection at the moment (hence the ugly "Properties" button in the makeshift toolbar) so that's the next big thing to knock over.