I've noticed that I write software in one of three modes:
- For myself: Shortcuts, less testing, not well-factored.
- For myself but in public: Mostly POP Forums, which I try to avoid letting it suck since others will use it and see the code.
- For sharing: Any day job or gig where others will use or maintain your code. You don't want to unleash crapsauce on others.
I have to admit that second case isn't the most clean of endeavors. While I'm generally happy with the forum app and the feedback I get for it, it needs some refactoring in places. The thing that bothers me the most is that a lot of the controllers do way too much. This is particularly obvious because of all the mocking required for the tests. It's not like I've got inline SQL in there, but they could definitely stand to delegate stuff to other stuff.
One of the inevitable things you end up doing at some point in your ASP.NET MVC controller is access the HttpContext in some way. Because the cats that build the MVC framework are so smart, they actually used HttpContextBase as the type for the HttpContext property on the Controller base class. That already makes life a little easier, because you don't have to mock out a huge graph of objects to test what it is your controller is doing.
I suggest that you can take that one step forward. For example, say that you need to molest your model a little before you return it to a view, but only if the client is a mobile browser. It's actually pretty easy to check, but here's the Boolean that tells you:
var isMobile = HttpContext.Request.Browser.IsMobileDevice;
Simple enough, but it's also pretty deep in the object graph for mocking. It also assumes you'll never do any logic more complicated than checking the property. Since you're already using dependency injection in your controller (and if you're not, shame on you, go read up on it), it might be easier to hand off this logic to something else. So in this example, perhaps you have a class called MobileDetectionWrapper, which implements IMobileDetectionWrapper, and looks like this:
public class MobileDetectionWrapper : IMobileDetectionWrapper
{
public bool IsMobileDevice(HttpContextBase context)
{
return context.Request.Browser.IsMobileDevice;
}
}
Super simple example, and what might seem like a needless abstraction, but this is far easier to test. Inject the IMobileDetectionWrapper into your controller, and now you simply mock that. Your test might look something like this (using Moq here):
var mobileDetection = new Mock<IMobileDetectionWrapper>();
mobileDetection.Setup(x => x.IsMobileDevice(It.IsAny<HttpContextBase>()).Returns(true);
var controller = new MyController(mobileDetection.Object);
var result = controller.MyActionMethod();
// test the result here for whatever
And just in case you're unclear about the way the controller looks:
public class MyController : Controller
{
public MyController(IMobileDetectionWrapper mobileDetection)
{
_mobileDetection = mobileDetection;
}
public ActionResult MyActionMethod()
{
var isMobile = _mobileDetection.IsMobileDevice(HttpContext);
// do stuff
return View(resultModel);
}
}
Get it? I freehand-typed that without Visual Studio or Intellicrack, so hopefully it's right. :) In any case, the dependency injection resolver you have set up in your MVC app news up the controller with the concrete implementation of IMobileDetectionWrapper and you use it in your action method. Again, trivial example, but imagine you had to do other special things, like check for a cookie and identify an iPad, and therefore return a false value instead of true for the IsMobileDevice question. The necessary mocking in the controller is significantly less.
Let me tell you a story of HR-discouraged workplace fun. Back in the day, prior to the crash-and-burn of Insurance.com, we had this thing in the development part of the company called the Scoring Game. I wrote about it a couple of years ago on my personal blog. The long and short of it is that we kept a running total of +/-1’s for virtually anything you can think of, for each participant. This was back in 2006, before it became trendy to do it for everything else on the Internets.
Later, Digg started doing all kinds of voting, and it was really the first active example that I can think of that I used in terms of measuring value of content (yes, slashdot did it, but I never went there). Various forums started doing it. StackOverflow based much of its value on a scoring system, along with achievements. When I worked at Microsoft, I worked on the reputation system that feeds the various MSDN properties. It seems inevitable that I’d have to add something like this to POP Forums.
Originally, I was thinking just in terms of voting up posts, but then I realized that there were actually two things to build. The voting mechanism was one part, but the actual scoring was a second part that should be decoupled from the voting. So the workflow goes like this:
Process Event –> Publish to user profile (optional) –> Get associated awards –> Qualify awards –> Give award
To use the system, you only need only a few lines of code. Use the dependency injection container (Ninject) to get the implementation of PopForums.ScoringGame.IEventPublisher.
Note: Yeah, the forums are currently wired to use ASP.NET MVC’s IDependencyResolver to new-up stuff. I realize that this is suboptimal, and a future version will fix this so you don’t have to commit to the same DI container the forum uses.
var publisher = PopForums.Web.PopForumsActivation.Kernel.Get<PopForums.ScoringGame.IEventPublisher>(); publisher.ProcessEvent("message for feed", user, "TestEventID");
Pretty simple, eh? The first string is the text that will be published to the user’s feed (if the event is set to publish), the second is the PopForums.Models.User object to associate with the event, and the third is the actual event ID. Event definitions are really simple.

There are three events that are static, permanently built into the system. These are wired into the post voting, and the creation of new topics and posts. So for example, when someone votes up a post, a string of HTML is passed in to the ProcessEvent() method, with the user object associated with the post, and the event ID PostVote. The resulting mention in the user’s profile looks like this:

Events don’t have to be published to the user’s profile, and they don’t even need to assign points. New posts and topic events fall into this category. So what’s the point then? Awards! POP Forums leaves that up to you. Award definitions are super simple as well. Say we wanted to give an award for anyone who made 50 posts. The definition would look like this:

We can assign any combination of events to the award. In this case, we look for 50 NewPost events, but we could just as easily require 25 PostVote events as well, for a combined set of conditions.
That’s really all there is to it. You can set up stuff anywhere in your app to record events, and publish them to the user profile. Give points, give awards. Knock yourself out!
Just wanted to drop a quick note to say that I've got an updated version of our most recent POP Forums drop. The new v9.2.1 adds Spanish along side of Danish, German and English as available languages. It has no new features or bug fixes, so if you have v9.2.0, and you don't need Spanish, these aren't the droids you're looking for.
Want to translate to yet another language? Drop me a line: jeff@popw.com.
POP Forums v9.2.0 is the third release for the ASP.NET MVC3 version of POP Forums. It is feature complete, stable, and ready for feedback. For previous release notes, see previous releases.
Check out the live preview: http://popforums.com/Forums
Setup instructions are available in the documentation section.
Upgrading?
If you're upgrading from v9.0 or v9.1, simply replace the existing files. You'll also have to run the PopForums4.xto4.2.sql SQL script against your existing database. That script can be found in the database project. It adds a number of new fields and tables.
What's new?
- Localization: The app can now be easily translated. .resx files included for Dutch (nl) and German (de) so far, in addition to the core English. Can you help with another translation? Contact jeff@popw.com.
- Vote up posts: Give credit to people who make good posts, see who voted on each post.
- The Scoring Game: Extensible system that allows you to give users points, and issue awards based on repeated events. For example, you can set up awards based on a number of new posts or topics (both of which record these events).
- Fix: Weird line breaks in lists when posting from Firefox parsed correctly.
What's next?
We'll get some sample documents around how you can use the scoring game functionality in your own application. Feel free to submit feature requests to the issue tracker or on the sample forum. We're particularly interested to hear if you have any desire for installation via NuGet, and if there's a desire to use a SQL CE database.
Starting with v9.2, POP Forums will be fully capable of localization.
I'm looking for people who can help translate the .resx file in this open source project, which is
fairly straight forward. I'll take help for any language, but I'm
particularly interested in:
- German
- Spanish (es-ES and es-MX)
- French
- Russian
- Chinese (zh-CN)
- Arabic
- Hebrew
If you can help, please drop me a line at jeff@popw.com. Thanks!
There was a problem in v9.1.0 that prevented user views of a topic to be registered, meaning the "new topic" indicator would continue to glow "new" even though the user had viewed it. This has been fixed in v9.1.1.
See the previous post about the new version. Get the bits here. Sorry for the bug... I didn't have solid testing around this particular feature. I do now!
Sometimes I read something in the "tech press" about Microsoft and get endlessly annoyed. I may have decided to leave the company, but quite honestly it's a lot like the feeling you get when you graduate from college. For better or worse, it'll always be a part of you and you'll always identify yourself as some part of it.
So ZDNet posts some drivel about blogs and such from Microsoft, and gets it wrong right off the bat:
"But the Microsoft blogs are the 'official' place to get detailed information; sometimes prepared and checked by the lawyers, more often posted directly by the developers working on the technology."
Really? I know a lot of people who work at Microsoft who have blogs, and they're not bouncing anything off of lawyers. Believe it or not, the company generally seemed to trust people to not do stupid things. The company is not as dumb and slow as people might like to think. It's also worth mentioning that many Microsoft employees host and pay for their own blogs, and a lot of people on these blog sites (MSDN, asp.net, etc.) don't work there at all.
That was just the part setting the tone that annoyed me. It was later in the piece where they express shock and awe (and then backtrack) over the use of open source at Microsoft.
"There's always a lot of suspicion when Microsoft is involved with open source, but this is a classic example of what open source is really good for..."
I hate that statement, because it comes off as an underhanded compliment. I read, "The evil Microsoft is trying to crush something, but it's cool because open source is a good force in the universe." There is not "always" suspicion, just suspicion when you're link-baiting. Mission accomplished.
Let me break it down for you in real terms. People like Matt (the developer who posted his experience about developing and deploying RequestReduce) at Microsoft are not cogs in the machine who mindlessly do as they're told and chant "developers developers" all day. In fact, Matt was one of the guys I worked with. We'd all go to lunch together (we had a DL called "deveats") and talk about whatever, make fun of our coworkers and often talk about poop (several of us had young children). We used all kinds of open source stuff in our apps, and obviously many of us contribute to, or maintain OSS projects. And by the way, the people who work there are probably smarter than everyone you work with, but would never admit to it.
My point is that actual human beings work at Microsoft, and this perpetual stereotype of the evil Uncle Fester working at the top to crush everyone is stupid and lame. It's also very tired. For all of the unfounded toxicity directed at Microsoft, the same people sure do get excited to see it on your resume.
Finally! After moving, being a dad and engaging in a great deal of home improvement, I finally managed to find time to an update out to POP Forums. I hope to not be that guy anymore, going forever between updates.
Release Notes
This is the first release for the ASP.NET MVC3 version of POP Forums. It is feature complete, stable, and ready for feedback. For previous release notes, see previous releases.
Check out the live preview: http://preview.popforums.com/Forums
Setup instructions are available in the documentation section.
Upgrading?
If you're upgrading from v9.0 to v9.1, simply replace the existing files. You'll also have to run the PopForums4.0to4.1.sql SQL script against your existing database. That script can be found in the database project. It adds a single field to the pf_Forum table.
What's New?
-
New "adapter" interface for forums. Using the IForumAdapter interface, a developer can plug-in code that alters the model and/or resulting view on topic lists and the actual threads. For example, you might add to or alter the model, then present a different view to display the data. See the comments on the IForumAdapter interface for more information.
- Also new, users starting a reply will see a button indicating that they can load any new posts that have occurred since they started writing their apply, so they don't miss any of the conversation.
- Fix: Moderating topic title doesn't update the UrlName.
- SEO enhancement: Page links in topics and forums include rel="next" and rel="prev" to tell search engines there's more to look at.
- Fix: User post list had broken markup, preventing topic preview.
- Fix: Added missing permission checking on action methods to preview or load individual posts.
- User name in top nav now acts as a link to the user's profile.
- Fix: Cache key for caching view post roles was incorrect.
What's Next?
Next batch of work will include an extensible "vote up" system to measure the usefulness of a post, and recognize users who have popular posts. The idea will be to make it open enough to work with any "scoring" actions you might develop in your site.
I was very relieved to see that Umbraco is ditching XSLT as a rendering mechanism in the forthcoming v5. Thank God for that. After working in this business for a very long time, I can't think of any other technology that has been inappropriately used, time after time, and without any compelling reason.
The place I remember seeing it the most was during my time at Insurance.com. We used it, mostly, for two reasons. The first and justifiable reason was that it tweaked data for messaging to the various insurance carriers. While they all shared a "standard" for insurance quoting, they all had their little nuances we had to accommodate, so XSLT made sense. The other thing we used it for was rendering in the interview app. In other words, when we showed you some fancy UI, we'd often ditch the control rendering and straight HTML and use XSLT. I hated it.
There just hasn't been a technology hammer that made every problem look like a nail (or however that metaphor goes) the way XSLT has. Imagine my horror the first week at Microsoft, when my team assumed control of the MSDN/TechNet forums, and we saw a mess of XSLT for some parts of it. I don't have to tell you that we ripped that stuff out pretty quickly. I can't even tell you how many performance problems went away as we started to rip it out.
XSLT is not your friend. It has a place in the world, but that place is tweaking XML, not rendering UI.
Whoa, I just realized that I never really announced here that I've decided to leave Microsoft. Actually, left, is more like it, since I'm currently on vacation. Nothing really exciting or controversial about it, just a list of reasons why it makes sense for me and my family. I wrote about it on my personal blog. I also summarized my experience there.
It was one of the hardest decisions I've made, but it was the right one. If I can say anything to the developer audience, it's that you are in good hands using Microsoft's technology stack. It just keeps getting better, and it was awesome to be a part of it.
Hopefully this means I'll have more time to mess with stuff and write more. My last position there was (and still is) all about stuff not yet ready for public consumption, which makes it kind of hard to write about. Meanwhile, I do have a point release for POP Forums for ASP.NET MVC in the pipe.
More Posts
Next page »