Monday, January 11, 2010

“Hello World” with FubuMVC (without the training wheels)

My previous post was a FubuMVC super quick-start which explained how to utilize some very helpful code that has been added into the Fubu source to allow you to get up and running fast. While this should suit most initial situations, there probably will be a point where you need to add your own conventions. I will walk you through creating your own bootstrapping code which will also explain how the “training wheels” from the previous post work. I am going to borrow heavily from Chad Myers’ explanation’s which he posted on the FubuMVC Google Group, because I could not have said it better.

  1. (Starting from the previous posts step #11) Add a “Global.asax” file and delete all the generated methods except “Application_Start”. In “Application_Start” add the following:

       1: public class Global : System.Web.HttpApplication {
       2:     protected void Application_Start(object sender, EventArgs e) {
       3:         var routeCollection = RouteTable.Routes;
       4:         FubuStructureMapBootstrapper.Bootstrap(routeCollection);
       5:     }
       6: }

  2. Create a FubuStructureMapBootstrapper.cs class that implements the IBootstrapper interface from StructureMap and then implement it’s members. This class manages the starting of Fubu and StructureMap together.

       1: public class FubuStructureMapBootstrapper : IBootstrapper {
       2:     private readonly RouteCollection _routes;
       3:  
       4:     private FubuStructureMapBootstrapper(RouteCollection routes) {
       5:         _routes = routes;
       6:     }
       7:  
       8:     public void BootstrapStructureMap() {
       9:         UrlContext.Reset();
      10:  
      11:         ObjectFactory.Initialize(x => { });
      12:  
      13:         BootstrapFubu(ObjectFactory.Container, _routes);
      14:     }
      15:  
      16:     public static void BootstrapFubu(IContainer container, RouteCollection routes) {
      17:         var bootstrapper = new StructureMapBootstrapper(container, new HelloWorldFubuRegistry());
      18:         bootstrapper.Bootstrap(routes);
      19:     }
      20:  
      21:     public static void Bootstrap(RouteCollection routes) {
      22:         new FubuStructureMapBootstrapper(routes).BootstrapStructureMap();
      23:     }
      24: }
    
    

  3. Create the HelloWorldFubuRegistry class that is passed into the StructureMapBootstrapper constructor along with the container. This is where all the actual Fubu conventions are located.

       1: public class HelloWorldFubuRegistry : FubuRegistry {
       2:     public HelloWorldFubuRegistry() {
       3:         IncludeDiagnostics(true);
       4:  
       5:         Applies.ToThisAssembly();
       6:  
       7:         Actions
       8:             .IncludeTypesNamed(x => x.EndsWith("Controller"));
       9:  
      10:         Routes
      11:             .IgnoreControllerNamespaceEntirely();
      12:  
      13:         Views.TryToAttach(x => {
      14:                               x.by_ViewModel_and_Namespace_and_MethodName();
      15:                               x.by_ViewModel_and_Namespace();
      16:                               x.by_ViewModel();
      17:                           });
      18:     }
      19: }
    

  4. IncludeDiagnostics(true) – Enable the diagnostics to be accessible through the /_fubu and /?fubudebug=true querystring options
  5. Applies.ToThisAssembly() – Tells Fubu to perform the following registration steps by scanning this assembly
  6. Actions.IncludeTypesNamex(x => x.EndsWith(“Controller”)) – Tells Fubu how to identify which classes containing action methods (i.e. HomeController)
  7. Routes.IgnoreControllerNamespareEntirely()  -- By default, Fubu will create a route for each action like /namespace/controllerbasename/action. Normally you wouldn't want /fubumvc/helloworld/controllers/home/home/home, you'd just want /home/home or /home/index or whatever. "IgnoreControllerNamespaceEntirely" does that. There are numerous variations of how to arrive at the route name here. Otherwise, you can specify your own conventions and manage the process.
  8. Views.TryToAttach --  This is a fall-through for matching actions-that-should-render-views (as opposed to actions that should render JSON) to their corresponding views.  It goes as follows:

      1. Try to match a view that is strongly typed (i.e. IFubuView where TModel is the return/output type of the Action), *AND* is in the same Namespace as the Controller/Action class *AND* is named the same as the Action/Method name (i.e. Home() -> Home.aspx)

      2. Try to match on the model *AND* the Namespace

      3. If all else fails, try to find a view anywhere in this assembly that matches the model type (Meaning that you don’t need to have the controllers and views in the same folder)

  9. Just in case you missed it, perform the same web.config tweaking like in the previous post.
I added this to my personal Google Code repo folder here. I anticipate that this, or something like it, will probably be moved to the Fubu code or wiki in the near future.

-Tim Tyrrell

Friday, January 8, 2010

“Hello World” with FubuMVC (Super Quick Start)

I started at Dovetail Software near the end of last year and the guys were gearing up to strip out the “proto-fubu” framework from their current project and rewrite the existing FubuMVC code; which is now complete. This week Brandon and I messed around and created a sample application to get more familiar with the framework. These are the steps that we used to get a quick sample up and running (made *much* easier by Chad and Josh last night).

  1. Get FubuMVC source from the “reboot” branch using something like TortoiseSVN at http://fubumvc.googlecode.com/svn/branches/reboot/ (soon to be Git). A sample application very similar to what is listed below is in the src/FubuMVC.HelloWorld folder
  2. Get Ruby to build it by navigating to the base FubuMVC folder and run a “rake” command (I am using “Ruby-186-27”, but any should work) or just open the solution and compile it.
  3. Create an ASP.NET Web Application project. Create a “lib” folder on the file system next to the newly created project
  4. Grab all the files (not just the three DLL's below) from the %yourFubufolder%\build folder if you raked, or %yourFubufolder%\src\FubuMVC.Container.StructureMap\bin\Debug folder if you built it through Visual Studio, copy them to a “lib” folder mentioned above, and then add three references to your project
    1. StructureMap.dll
    2. FubuMVC.Core.dll
    3. FubuMVC.StructureMap.dll
  5. Also add a reference to “System.Web.Routing” if you want to make the squiggle’s in your web.config go away
  6. Delete the “Default.aspx” file and the App_Data folder
  7. Create a Controllers Folder and then add a Home folder underneath it
  8. Add a Home.aspx Web Form page into the Home folder, have it inherit from the FubuPage<TViewModel> class instead of the Page class (FubuPage inherits from Page) and create an output view model to plug into that spot
       1: using FubuMVC.Core.View;
       2:  
       3: namespace FubuMVC.HelloWorld.Controllers.Home
       4: {
       5:     public class Home : FubuPage<HomeViewModel>
       6:     {
       7:     }
       8: }

  9. Add a HomeContoller.cs class to the Home folder and add a method that returns the previously created output view model, HomeViewModel and accepts a new input model
       1: namespace FubuMVC.HelloWorld.Controllers.Home
       2: {
       3:     public class HomeController
       4:     {
       5:         public HomeViewModel Home(HomeInputModel model)
       6:         {
       7:             return new HomeViewModel {Text = "Hello, world."};
       8:         }
       9:     }
      10:  
      11:     public class HomeViewModel
      12:     {
      13:         public string Text { get; set; }
      14:     }
      15:  
      16:     public class HomeInputModel
      17:     {
      18:     }
      19: }

  10. Get the text out of the returned Model and display it on the view (I yanked out the server tags, although that is not necessary)

  11.    1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Home.aspx.cs" Inherits="FubuMVC.HelloWorld.Controllers.Home.Home" %>
       2:  
       3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       4:  
       5: <html xmlns="http://www.w3.org/1999/xhtml" >
       6: <head>
       7:     <title></title>
       8: </head>
       9: <body>
      10:     <div>
      11:         <%= Model.Text %>
      12:     </div>
      13: </body>
      14: </html>



  12. Add a Global.asax file to the project, but instead of inheriting from HttpApplication, inherit from FubuStructureMapApplication:

       1: using FubuMVC.StructureMap.Bootstrap;
       2:  
       3: namespace FubuMVC.HelloWorld
       4: {
       5:     public class Global : FubuStructureMapApplication
       6:     {
       7:     }
       8: }

  13. If you want to turn on the diagnostics from Jeremy’s article, switch the web.config debug="true"and the diagnostics will be enabled. Otherwise you can set it yourself below.

  14.    1: using FubuMVC.StructureMap.Bootstrap;
       2:  
       3: namespace FubuMVC.HelloWorld
       4: {
       5:     public class Global : FubuStructureMapApplication
       6:     {
       7:         public Global()
       8:         {
       9:             EnableDiagnostics = true;
      10:         }
      11:     }
      12: }

  15. Lastly, we took out the machete on the web.config file. Although, we did add some references to System.Web.Routing inside of it.
       1: <?xml version="1.0"?>
       2: <configuration>
       3:   <configSections/>
       4:   <appSettings/>
       5:   <connectionStrings/>
       6:   <system.web>
       7:     <compilation debug="false">
       8:       <assemblies>
       9:         <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
      10:         <add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      11:       </assemblies>
      12:     </compilation>
      13:     <authentication mode="None" />
      14:     <pages>
      15:       <controls/>
      16:     </pages>
      17:     <httpHandlers/>
      18:     <httpModules>
      19:       <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      20:     </httpModules>
      21:   </system.web>
      22:   <system.codedom>
      23:     <compilers>
      24:       <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
      25:                 type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      26:         <providerOption name="CompilerVersion" value="v3.5"/>
      27:         <providerOption name="WarnAsError" value="false"/>
      28:       </compiler>
      29:     </compilers>
      30:   </system.codedom>
      31:   <system.webServer>
      32:     <validation validateIntegratedModeConfiguration="false"/>
      33:     <modules>
      34:       <remove name="UrlRoutingModule" />
      35:       <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      36:     </modules>
      37:     <handlers>
      38:       <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      39:     </handlers>
      40:   </system.webServer>
      41: </configuration>

  16. Add the project path to new application in IIS (or Cassini) and hit the URL: http://localhost/%yourapp%/home/home

image


Screenshot of final folder structure and references:

image

Code location: An application very similar to this is located in the reboot branch of FubuMVC, called FubuMVC.HelloWorld in the src folder here

Let me know if I missed anything or if this does not work. A lot will be done in the next couple of weeks to get Fubu rocking, and I plan on blogging as much as possible along the way. As you probably heard, we are starting up a posse: http://wiki.fubumvc.com/TODO

-Tim Tyrrell

Tuesday, January 5, 2010

2010 Goal List

I figure that I better document my 2010 goal’s before it gets too far into the new year. Per my previous 2009 goals, I actually did a pretty good job achieving them. I wrote about my accomplishment’s below but then I deleted it, because even I was bored! :)

  1. I am getting back into the typing. I feel like Kevin Costner in “Robin Hood : Prince of Thieves” when someone comes behind me at work; I start typing like an idiot and shoot my arrow in the bushes.
  2. I used to play guitar; I even took lessons in high school and a classical guitar class in college. This weekend I changed the strings on my acoustic for the first time in 10 years. I plan to get back into playing and my fingertips are already hurting.
  3. Most of my work experience is with .NET. I really enjoyed working with Unix when I was at a previous job and want to learn a different MVC framework and a dynamic language, so Rails is where I am setting my sights. I have an Ubuntu Linux VM setup with VirtualBox and have been working through some tutorials. I really want to attend the Austin On Rails meetings and hope that I go.
  4. I also will continue my .NET journey and have some great people to guide me now that I work at Dovetail Software. My current goals are to be competent and comfortable at unit testing/TDD and to understand fubuMVC inside-out.
  5. I will continue to attempt fitting a game of tennis in every week, it appears that I actually work with a couple of tennis players, so I may have lucked out.

That’s it. Done.

Sunday, October 11, 2009

NWA DNUG - Jimmy Bogard (and me!)

Come join the NWA .NET User Group on October 13th at 5:30 PM. We will be taking nominations for the upcoming User Group officer election's and will have dinner catered from Sonny's Barbeque courtesy of GDH Consulting.

Main Presentation
Title: Testing the Last Mile with UI Testing

Description: The ASP.NET MVC framework greatly improved the web testability story in .NET, allowing for testing of the various components of MVC including controllers, filters, binders and more. But testing these components in isolation still doesn't prove that your site works as a whole. Action methods tested by themselves don't prove that the view shown has the correct information on it, or that links work as expected. For these types of tests, an end-to-end, browser-based test is needed. But just as it is difficult to test APIs not designed for testability, views not designed for testability can lead to brittle, difficult to understand tests. In this session, we'll look at the popular UI testing frameworks, and pros and cons of each. We'll also look at design for UI testability in our MVC application, and how we can greatly ease our testing burden with design techniques in our views. Finally, we'll look at UI test design as a whole, and examine how we can develop a complete UI testing strategy that eliminates the difficulty in testing the last mile.

Presenter: Jimmy Bogard is a principal consultant at Headspring Systems. He is an agile software developer with six years of professional development experience. He has delivered solutions from conception to production for many clients. The solutions delivered by Jimmy range from shrink-wrapped products to enterprise e-commerce applications for Fortune 100 customers. He is also a Microsoft Certified Application Developer (MCAD) and is an active member in the .NET community, leading open-source projects, giving technical presentations and facilitating technical book clubs. Currently, Jimmy is the lead developer on the NBehave project, a Behaviour-Driven Development framework for .NET, AutoMapper, a convention-based object-to-object mapper and the facilitator of the Austin Domain-Driven Design Book Club. Jimmy is a member of the ASPInsiders group, and received the "Microsoft Most Valuable Professional" (MVP) award for ASP.NET in 2009.

Lightning Presentation
Title: Mobile Web Development with ASP.NET MVC

Description: Learn how to use a custom view engine in ASP.NET MVC to make developing mobile web pages easier.

Presenter: Tim Tyrrell is a Chicago native relocated to Bentonville, AR, to build websites for Wal-Mart’s recycling and waste reduction initiatives. He is a co-founder of the Wal-Mart .NET User Group and an officer for the NW Arkansas .NET User Group.

Swag:

-Office 2007 Standard
-Wrox - C# 2008 Book
-Wrox - Professional ASP.NET 3.5 SP1 Edition: In C# and VB
-Resharper License
-Nevron Chart for .NET Lite Edition
-Codesmith Tool Personal Pro 5.x License
-Syncfusion Essential Studio ASP.NET MVC Edtion
-Component One Studio for ASP.NET
-Visual SVN Personal License

When:
5:30 PM - 5:45 PM - Welcome and News, Sign-in and Food
5:45 PM - 6:00 PM - Lightning Presentation
6:00 PM - 6:10 PM - Intermission – Presenter switch over
6:10 PM – 7:40 PM – Main Presentation
7:40 PM – 8:00 PM – Closing and Prize give-a-ways

Where:
The Jones Center
922 East Emma Avenue
Springdale, AR 72764
Room 226 (Kansas City Room)

Monday, May 11, 2009

NWADNUG: Jay Smith - Exposing Yourself with RSS and ATOM Syndication

Lightning Presentation


Title: 2009 Tech Salary Survey
Description
: Discussion about the current trends for 2009 in Tech Salaries.

  • Employee Concerns about Career Marketability
  • Salary Satisfaction
  • Average Salaries by Metro Area & Region
  • Average Salaries by Job Title & Industry
  • Average Salary of Skills, Years Experience, and Company Size

Presenter: Jeremy Wilson works for GDH Consulting as a recruiter. GDH Consulting provides professional services solutions in Information Technology and Business Management uniquely tailored to the needs of our clients. GDH has earned continuous repeat business from our client partners since 2001, and is recognized by Inc Magazine as one of the fastest growing companies in 2006, 2007, and 2008. I have been with GDH for 4 years as an Account Manager and Recruiter working with small, medium, and large sized clients in the NW Arkansas IT market.



Main Presentation


Title: Exposing Yourself with RSS and ATOM Syndication


Description: In just about every web application today some amount of information is exposed via RSS or ATOM feeds. Many frameworks have been developed to give your applications this functionality. With the release of Windows Communication Framework a new set of classes were added to allow for the creation and consumption of RSS and ATOM feeds right in the framework. This session will take an look at these classes and how they can be used to generate feeds of any kind from your application.


Presenter: Jay Smith works for Tyson Foods, Inc. where he is a PMO Architect and Evangelist, and is a former President of the Northwest Arkansas .Net User’s Group. Jay currently serves on the INETA Speakers Committee and works diligently with others on test bed projects to learn new concepts and designs. You can read more about Jay on his blog http://www.jaysmith.us or follow his tweets at http://twitter.com/jaysmith.
Jay regularly presents to user groups on various topic including Design Patterns, Visual Studio 2008, Enterprise Library, WPF, and Unit Testing. He is a registered speaker on Codezone, you can make speaker request through there or contact him directly.



Swag:


Resharper 4.5 License
Microsoft T-Shirt
Inside Microsoft Office SharePoint Server 2007 Book
Restful .Net Book
Inside Microsoft Exchange Server 2007 Web Services Book
Build a Program Now Visual Basic 2008 Book


When:
5:30 PM - 5:45 PM - Welcome and News, Sign-in and Food
5:45 PM - 6:00 PM - Lighting Presentation
6:00 PM - 6:10 PM - Intermission – Presenter switch over
6:10 PM – 7:30 PM – Main Presentation
7:30 PM – 8:00 PM – Closing and Prize give-a-ways


Where:
The Jones Center
922 East Emma Avenue
Springdale, AR 72764
Room 226 (Kansas City Room)


NetMeeting URL: http://snipr.com/nwadnug
Link RSVP URL: http://snipr.com/ha6du

Sunday, May 10, 2009

jQuery Intellisense with VS 2008 SP1 Tips

If you are a poor schlub stuck working on a ASP.NET Webforms project and not an ASP.NET MVC project, you may run into a few hiccups getting the jQuery Intellisense working along the way. Scott Guthrie has a great tutorial, but a couple of important steps are missing. I would like to mention that this is less of an issue with ASP.NET MVC because all of the required files are included in the default project template.



How Did I Get Into This Mess?


You would first go to jquery.com to download the “min” file which is (currently) titled “jquery-1.3.2.min.js”. Following ScottGu’s instructions, you would get the Visual Studio Documentation file linked from his page here and would end up with a documentation file named “jquery-1.3.2-vsdoc2.js”. There are two confusing aspects to this file name:

  1. It has the number “2” at the end of vsdoc
  2. It does not have the “min” section

Does this really matter? No, because all you need to do is match the original jQuery file name and add the text “–vsdoc” before the “.js”, but it adds to a rookies confusion.



The Big Finish


Since you are a pragmatic developer and wish to write unobtrusive javascript, you would create a separate js file and prefix it with this line:


/// <reference path="~/Scripts/jquery-1.3.2.min.js" />

Our new javascript file, the original “jquery-1.3.2.min.js” file, and our newly renamed “jquery-1.3.2.min-vsdoc.js” all reside in a “Scripts” folder. Now we can use jQuery Intellisense to chain the heck out of some methods.

$("#test").addClass('hidden').click();

Thursday, April 23, 2009

NWA Code Camp

Join us at the NWA Code Camp this SATURDAY at NWACC!



WHAT IS Northwest Arkansas Code Camp 2009?
CodeCamp events are designed for the software developer community at large. These events are put on by developers for developers all across the county. They are a place for developers to come and learn from their peers about topics that are always based on community interest. Code Camps are always free for attendees.



WHAT TOPICS will be presented?
A wide variety of topics of interest to the developer community including:


.NET
Unit Testing
LINQ
SharePoint
Design Patterns
SQL Server
WCF
Entity Framework
iPhone Dev



WHEN AND WHERE is the event?
Saturday, April 25th, from 8:30am to 5:30pm.
Shewmaker Center at Northwest Arkansas Community College



HOW can I learn more and register?
Visit the Code Camp website at http://codecamp.nwadnug.org/