GeoGeek.tv: Talkin Flex with Royce Simpson

Posted by Dave Bouwman | Posted in GeoGeekTV, Uncategorized | Posted on 08-10-2009

0

UPDATE: Apparently Royce has been slammed by the flu and will be re-scheduling – we’ll still talk Flex, and other random stuff though

Tomorrow, Oct 9th, we will be chatting with Royce Simpson, the developer who built the award winning City of Greeley “ORIGIN” mapping applications.

image

(Royce is on the right, Brian is on the left, and Jack is givin’ out the hugs)

We’ll talk about his background as a developer, what got him interested in Flex development, we’ll have him take us through the app and discuss various tools and how they were implemented.

Check out the apps, and join the chat to ask questions.

When: Oct 9, 2009 4:00pm MT

Where: http://geogeek.tv/live.aspx 

Follow Royce: @roycesimpson

Creating GeoGeekTV: Domain Model, Controllers and Views

Posted by Dave Bouwman | Posted in ASP.NET MVC, GeoGeekTV, jQuery | Posted on 31-08-2009

2

Now that we have the look and feel stubbed out, it’s time to build out the rest of the site.

Since nearly every page is data driven to some extent, the best place to start is with the domain objects. If we were doing this with Linq to SQL, we’d start by creating the database, and then having that drive our Linq to SQL “domain”, but I’m planning on using this project to get my feet wet with NHibernate, so I’ll just start with the domain.

Since the site is going to be pretty simple, we really don’t have a lot in the domain – really just a ShowModel and a TagModel as shown in the class diagram below.

domain-model

As we can see, these are simple data containers. I had originally thought I’d have a separate “UpComingShowModel”, but it seemed like it would be a pain to copy the info from that model into the “ShowModel”, so I just added an IsPlanned flag. This way I can keep both the upcoming and the completed shows in the same table, side-stepping this entire problem.

Some may ask – why call your domain entities “Models”. Well, that’s a good question. In some other apps I’ve been working on we started off calling the entities Models, and then realized that we needed more than just the entity in the View – so we added a set of “ViewModels” into the mix. This seemed to work pretty well on these other projects, but it does seem a little forced on a project this simple.

Repository

Now that we have the models, we need a way for the Controllers to access them. For that we implement a repository pattern using dependency injection – sounds more complex than it really is.

Essentially we define an interface for a data repository – IShowRepository in this case. This interface represents the contract between the consuming classes (the controllers) and the implementing classes (the data access layer). We then use a dependency injection framework (Castle Windsor via the mvccontrib library) to pass an implementation of the repository into the controller’s constructor. Trust me, this is really easy.

I tend to build these interfaces in an iterative manner – I’ll start with one page of the site, determine what domain objects I need in the controller (and thus the view), then I add methods to the repository interface to get these objects, and then provide the implementation. Here’s the IShowRepository as it currently stands…

repo-interface

After futzing with Visual Studio to show the full signatures (Class Diagram –> Change Member Format –> Display Full Signature), we can see that this is a very simple data contract.

Fakes

Since I want to “prove” the design before getting into actually creating a real data access layer, I start by cooking up a simple fake implementation of the repository. As far as the Controller knows, this is a full blown real-deal repository, but it’s just returning junk. As you can see by hitting the site right now, we are showing lists of shows, but they’re all the same thing – that’s because behind the scenes pretty much everything hits this private method:

private ShowModel CreateFakeShow()
{
    return new ShowModel(){
        Description = @"Dave and Brian talking about recent work,
        building GeoGeekTV.com, Flex, and NBB Hoptober",
        Title = "Friday Streaming from DTSAgile",
        ImageName="123abc.png",
        IsPlanned = false,
        DateLocation= "August 28th, Fort Collins",
        StreamedLive = true,
        ViewCount = 3,
        ShowNumber = 323
        };
}

Dependency Injection

Ok, so we have the interface and a fake implementation, and now we need to get this into the controllers. Since we will be using constructor based injection, the first thing to do is knock in some constructors for our controllers. This is pretty much the pattern for all the controllers.

private IShowRepository _showRepository;
public HomeController(IShowRepository showRepository)
{
    _showRepository = showRepository;
}

Next, we need to register our “fake” with Castle Windsor so it can do the injection. I’ve already setup the basic Castle Windsor infrastructure in Global.asax.cs, so all I need to do is register the fake with the WindsorContainer…

protected virtual void InitializeWindsor()
{
    if (_container == null)
    {
        _container = new WindsorContainer();
        ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(Container));
        //add in the components...
        _container.AddComponent<IShowRepository, GeoGeekTV.Fakes.ShowRepository>();
        //Add the controllers...
        _container.RegisterControllers(typeof(LoginController).Assembly);
    }
}

You can get the basic Castle Windsor for MVC setup from looking at either the source code for this project, or from mvccontib’s examples.

That’s about it! With the Windsor container in place, ASP.NET MVC will use it’s factory to create the controller, and along the way all the dependencies get injected. See – I told you it was easy!

Controllers and Views

I’m not going to go the basics of ASP.NET MVC – I’d suggest reading the NerdDinner example from Scott Guthrie, Phil Haak, Scott Hanselman and Rob Conery. I’ll also throw out a pitch for their book, as it is quite good.

In the earlier post I defined the routes, which helped map out the controllers, and the needed methods. Since I’ve built a few sites, and have some handy code lying around, I also inherited my controllers from a BaseController than has some logging capabilities baked in.

basecontroller

Most of the controller methods are very simple – just populate a ViewModel from the repository, and pass that to the view.

This is pretty representative – it’s the Home Controller’s Index method, which is the main page of the site…

public ActionResult Index()
{
    HomeViewModel model = new HomeViewModel();
    model.MostViewedShows = _showRepository.GetMostViewedShows();
    model.RecentShows = _showRepository.GetRecentShows(5);
    return View("index",model);
}

In some projects I’ve had the repository build up the ModelViews, but in this one, it’s easier to have the controller’s handle this, as it results in much less code in the repository.

Summary

So – the project is coming together. Almost all the pages are built out – the Contact page needs serious CSS attention, as well as a back-end implementation. Looking forward, I still have a fair bit of work left to polish everything off. Luckily, I think the enhanced HtmlHelpers in ASP.NET MVC 2.0 will help out. Next up: The Admin Pages

Creating GeoGeekTV.com: Implementing the Design

Posted by Dave Bouwman | Posted in ASP.NET MVC, GeoGeekTV, jQuery | Posted on 28-08-2009

1

Welcome back to my on-going series about the creation of GeoGeekTV.com. With the solution set up, it’s time to setup the master page. For this site I’m using the 960 grid system (960.gs). This is a super easy to use CSS grid layout system. The basic idea is that you start from a 960px wide layout. From there you pick either a 12 or 16 “column” layout for a block of your page (a div), and then drop more divs inside that using classes to specify the width. Sprinkle in some clears, and it all just work. It makes more sense to look at it.

<div class="header">
    <div class="container_12">
        <div class="grid_8">Header Image</div>
        <div class="grid_4">
        <ul id="headerNav">
        </ul>
        </div>
    </div>
    <div class="clear"></div>
</div>

<div class="content">
    <asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
<div class="footer">
    <div class="container_12">
        <div class="grid_5">Recent Show List</div>
        <div class="grid_7">TwitterFeed</div>
        <div class="clear"></div>
        <div class="grid_12">
            <ul id="footerNav">
            </ul>
        </div>
        <div class="clear"></div>
    </div>
</div>

That the stripped down layout for the whole page. We have the three main sections (header, content, footer) which are horizontal color bands in the layout (see the image below). Inside each of them I’ve setup a 12 column container div (<div class="container_12"> ). Inside of that div, I’ve dropped a few div’s with “grid_XX” classes. What’s super cool is that as long as the XX’s in a container add to 12 (or 16 if you’re using the 16 column version) you’re good.

If this does not make sense, take a read at http://960.gs.

From there, I cut graphics out of Illustrator, and implemented a very simple home page.

ggtv-home

You can check out the site as it progresses – I’m now pushing updates to GeoGeekTV.com

Clearly there is work to do on the styling, and I’m going to change up a few graphics, but we’re on our way.

One neat thing I grabbed was some code for putting descriptions over the show screen caps.

ggtv-overlay

As you mouse over the image, the title of the show and the show description slide in. This jQuery goodness is courtesy of Kevin Liew of Queness.com – check out the article for more info. The more I work with it, the more I love jQuery.

That’s it for now. If you want to check out the code, the source is all up at http://subversion.assembla.com/svn/GeoGeekTV

Next up:

Baking the cake with repositories, controllers and fakes! I’ll be creating the domain model, defining the repository interfaces, implementing those interfaces with fakes, and then wiring them into the controllers. Should be fun!

Creating GeoGeekTV.com: Solution Setup

Posted by Dave Bouwman | Posted in ASP.NET MVC, GeoGeekTV, jQuery | Posted on 27-08-2009

5

Welcome back to my on-going series about the creation of GeoGeekTV.com. Now that I’ve got the routes all setup, it’s time to setup the solution.

Typically I break things up into (at least) 4 projects: Site, Domain, Data and Fakes.

ggtv-soln

Depending on what I’m doing I may create 3 more projects that will have unit tests for the previous three (I don’t create tests for the fakes!). Since this site will be pretty simple, I’ll likely skip unit testing for all but the most complex stuff.

So let’s see what’s in these projects

GeoGeekTV.Site

This is the actual ASP.NET MVC project. We’ll have the controllers, and the views in here, as well as some Html Extensions, Action Filters and Services. Since I like to use dependency injection to pass data repositories and other services into my controllers, I setup the mvccontrib WindsorControllerFactory. Since I’m using ASP.NET MVC 2 (Preview 1), I had to grab the /mvc2 branch of the source from github. Everything built smooth as silk, so all I did was grab the dlls and drop them into the /lib folder and make references.

Other items of interest… I’m using a custom authorization filter, which is based on the out-of-the-box Authorization filter that ships with ASP.NET MVC 1.0. Since the source for ASP.NET MVC is available, I could peek at what they did and just change a few things! It’s nice because it ties in with my custom Forms Authentication system, which uses an AccountModel. When a user logs in, their AccountModel is stashed away in session and is used by the Auth Filter to check a user’s roles. This allows us to avoid the Membership provider mess, and just implement things however we want to, all the while hiding the dirty bits behind a nice clean IAccountRepository interface.

GeoGeekTV.Domain

This is where the meat of the project lives – the domain model. In most projects we have the things we need to persist in the database as well as things like SelectLists that are just needed for the presentation in the UI. After trying a number of approaches, I’ve settled on keeping these things separate.  The classes that are persisted to the database are “Models”, and the classes which contain the models as well as the UI extras are “ViewModels”.

This works well because we can create strongly typed views against our ViewModels, which allows us to have all the select-list-drop-down goop and the Model in one handy container, while still keeping them separate behind the scenes. We’ll see how this comes together in a later post.

We also have some utility classes in here, as well as the interface definitions for services and repositories.

 

GeoGeekTV.Data

This is the data access layer, and we’ll have classes in here that will implement the IRepository interfaces. For now there’s nothing in here, but eventually we’ll have our NHibernate stuff in here.

 

GeoGeekTV.Fakes

This is where we fake it till we make it. Basically we implement the interfaces in here, and just return valid, but fake data. This allows me to build out pretty much the entire site without every creating a database. Since it’s just code, any refactoring of the domain or data access interfaces has limited ripple effects. And since we use dependency injection in our controllers, we just change one line of code and the app switches over to the real implementation in the Data project.

Ok, that’s the solution. Next up: Implement the design via a master page.

Creating GeoGeekTV: Setting up Routes

Posted by Dave Bouwman | Posted in ASP.NET MVC, GeoGeekTV | Posted on 24-08-2009

4

Welcome back to my on-going series about the creation of GeoGeekTV.com. Having solidified the design, we can move on to the implementation.

Since ASP.NET MVC abstracts the requested URL from actual files on disk (as in /foo/bar.htm does not actually load a the bar.htm file in the foo folder), we have a lot more control of the Urls. Thus, it’s worth taking a little time at the beginning of a project to decide how we want the Urls to work

For GeoGeekTV, we have a few main areas: Home Page, the Live Stream, Upcoming Shows, the Archive, a Contact page, Backstage and Admin.

Since most of these are pretty simple pages, we can use the default routing for the most part.

The default route  uses the /{controller}/{action}/{id} pattern to make an incoming request to a controller and action (aka a method).

When we setup routes, we assign defaults to the components of the route. So for our site, we users to land at the home page, so we setup the default for the route to be “home”. As for a default action, we usually use “index”. Since an id does not have much context on some controllers, we default that to an empty string.

This is what the route looks like in the Global.asax.cs file:

routes.MapRoute(
    "Default",                                              // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

I like to map out the urls for an application in a table. This helps get an idea of how the routes should be setup, and it also provides a development road map for the controllers and actions we’ll need.

Url Controller Action Description
/Home Home Index The home page
/Live Live Index The live streaming page. If we are not live, show a list of recent shows
/Archive or

/Archive/List
Archive List Paged list of Archive shows
/Archive/View/{name} Archive View View a show from the archive
/Archive/tag/{tag} Archive tag View list of shows that have a particular tag
/Contact Contact Index The Contact form
/Backstage Backstage Index The backstage page
/Upcoming Upcoming List List of upcoming shows
/Upcoming/Edit/{id} Upcoming Edit Edit an upcoming show
/Upcoming/Create Upcoming Create Create an upcoming show entry
/Archive/Create Archive Create Create an entry in the archive
/Archive/Edit/{id} Archive Edit Edit an entry in the archive
/Login Login Index Login screen
/Admin Admin Index Main Admin Screen

Conveniently, for GeoGeekTV.com we can pretty much live with this default route, with one exception.  We are going to support a simple tagging system on the shows, and it would be handy to have a url that would list all the shows related to a tag. Now, if we wanted to use the ID of the Tag in the url (i.e. the “Unit Testing” tag has an ID of 27, so the url would be /Archive/Tag/27) our default route would still work. But I think it would be more useful to have human readable tags, so we’ll use the actual tag in the url.

So I’ll create an additional route.

routes.MapRoute(
    "Archive",                                                // Route name
    "Archive/Tag/{tag}",                                      // URL with parameters
    new { controller = "Archive", action = "Tag", tag = "" }  // Parameter defaults
);

This new route is very specific – it only applies to the /Archive/Tag url, and will now pass in a parameter named “tag” to the controller method.

 

Testing the Routes

We can write unit tests to ensure that the routing is working as designed. Since this is just testing the routing, we don’t actually need to create any controllers or views – we are just testing the routes in Global.asax.cs

[Test]
public void archive_tag_tag_route()
{
    MvcApplication.RegisterRoutes(RouteTable.Routes);
    var httpContext = MockRepository.GenerateStub<HttpContextBase>();

    httpContext.Stub(x => x.Request).Return(MockRepository.GenerateStub<HttpRequestBase>());
    httpContext.Request.Stub(x => x.PathInfo).Return("");
    httpContext.Request.Stub(x => x.AppRelativeCurrentExecutionFilePath).Return("~/Archive/Tag/foo");

    var routeData = RouteTable.Routes.GetRouteData(httpContext);
    Assert.AreEqual(routeData.Values["controller"], ("Archive"));
    Assert.AreEqual(routeData.Values["action"], ("Tag"));
    Assert.AreEqual(routeData.Values["tag"], ("foo"));
}

Although this is somewhat long-winded, and there are other more elegant options, I just keep this snipped of code lying around and drop it in as needed.

Although pretty simple at this point, I’ve pushed this into the repository over on assembla.com if you want to check out the code.

Up Next:

We’ve already created a simple out of the box ASP.NET MVC 2 web application. Next time we’ll layout the other projects in the solution, clear out the un-needed cruft from the MVC project and setup our dependency injection. From there we’ll actually start writing some code!

Behind the Scenes: Creating GeoGeekTV.com

Posted by Dave Bouwman | Posted in ASP.NET MVC, GeoGeekTV, Usability | Posted on 17-08-2009

2

For a while now I’ve been wanting to do a “behind the scenes” series of posts where we showing how we work, but most of our projects are either sensitive in nature, or just too large to do without making it a 200 part series. I was also following along last week as the team at Carsonified.com whipped up a simple ASP.NET MVC app. I thought this was particularly interesting to follow since these guys are usually a Ruby shop.

Anyhow, since I’m just starting to build GeoGeekTV.com, I thought this was as good an opportunity as any.

The Goal

As nice as UStream.tv is, I’d rather like to have better “experience” for GeoGeekTV.com. I still want to keep is really simple, but just make it a little smoother to locate archive shows, and to see what we have upcoming. We also want to have a consistent location to watch the “live” stream.

Wireframes

To start off, I fired up Basalmiq (full disclosure – they hooked me up with a license if I blogged about it – I’ll do a specific post in it’s pros and cons another time). In the past I’ve used Visio for developing wireframes, but the tendency there is to get too involved in making it look “real”. For me at least, wireframes are more about figuring out the basic interaction model – how is the information organized, and how does a user navigate it. I’m not worrying so much about colors and fonts. Baslsamiq helps with this because it looks hand-drawn. This seems to help people focus on the flow instead of the looks.

Here’s the initial cut at the UI

GGTV-home-sm

Ok, so I did play with photoshop today and throw in a quickie site header, but you get the idea.

Keepin it “Agile”

In the past I’ve talked a lot about agile practices, so in keeping with that I’ll be keeping track of user stories and tasks at Scrumy.com. You can see the project by heading to http://www.scrumy.com/geogeektv but the screen cap below pretty much sums it up.

scrumy

Basically this is just a digital version of sticky notes. Since this is the free version, I think anyone can change or move things around, but please don’t ;-) Also – since this is a side project, I’m not really working in “sprints” per-se – I’m just doing tasks as I have time – I *hope* to have this all up and running for the next conference we attend (GIS in the Rockies).

Moving Forward

I’ll be working on furthering the design and graphics over the next week, and then I’ll start on the coding. I’m going to be using ASP.NET MVC v2 (beta) because I want to play with the nifty new bits, and I may use this as an opportunity to mix a little Fluent NHibernate into my bag o tricks as well. I’m going to throw the code up on Assembla, so anyone will be able to peek inside.

GeoGeekTV: Today @ 4:00pm

Posted by Dave Bouwman | Posted in GeoGeekTV | Posted on 29-05-2009

0

Just a quick note that we’ll be doing another edition of GeoGeekTV today at 4:00pm Mountain. We’ll be talking about "Bing Enterprise Geo-webby mashup silliness" as well as Flex, Silverlight, the beer of the week, and anything else that comes up in the chat. Drop by UStream http://www.ustream.tv/channel/GeoGeekTV  or just click on the graphic below.

geogeektv-white

GeoGeekTV May 8th @ 4:00pm MT

Posted by Dave Bouwman | Posted in GeoGeekTV | Posted on 08-05-2009

0

Given that Twitter is apparently down right now, I’ll opt to send out a notice that GeoGeekTV will be occuring at it’s usual time 4:00pm MT today Friday May 8th.

We’re moving to what we hope will be a permanent home at UStream. I will be setting up a separate site for the show and it’s eventual archive, but for now the url is: http://www.ustream.tv/channel/GeoGeekTV

As usual, join the chat, as some random questions, and we’ll try to answer them without excessive Rick Rolls.

This week Brian Noyle is taking his son to the Circus, so I’ll have Michael Hayden – one of our Javascript Dojo kung-fu experts with me. And as always – some Colorado beer to virtually share with you all.

GeoGeekTV: Today at 4:00pm Mountain…

Posted by Dave Bouwman | Posted in .NET, ArcGIS Devt, GeoGeekTV, GeoWeb, Life | Posted on 01-05-2009

2

For the last 3 weeks Brian Noyle and I have been doing some videocasting – really off-the-cuff type of stuff. We’ve tried a few different services Kyte.tv, Mogulus.com and UStream.com, and it seems that for most viewers Kyte.tv has worked the best.

kyte

Now that we’ve sorted that out, we’re hoping a wider audience will join in. Here’s how it works:

1) Brian and I visit a local beer store and return with a few cold ones.

2) We start the web cam, and crack the beers.

3) We talk about what we’ve been doing that week and take random GIS/Design/development questions from the audience (via chat)

4) Somehow an hour goes by, and it’s fun for all involved.

So – if you’re near a computer around 4:00pm Mountain time, pop over to http://www.kyte.tv/ch/288902-geogeektv and ask a question, chat with other geogeeks, or heckle us from afar.

You can check out a previous “show” here: http://www.kyte.tv/ch/276222-dtsagile

Moving forward, we’ll get some other people to drop by and do ad-hoc interviews, and generally carry on about whatever seems interesting. Hope you can join us!