Archive for July, 2008

Learn NHibernate with The Summer of NHibernate

July 31st, 2008

Summer of NHibernate Screencast Series

“a series of successive screencast sessions that cover the complete use and implementation of NHibernate”

Humor: ‘If programmers have to make a plane’

July 28th, 2008

View uTube Video

I enjoyed this one   :)

This is the scrum/agile approach at it’s finest  :)

ASP.NET MVC and Silverlight

July 24th, 2008

I’m not going to dwelve too deep into Silverlight, as I’m just learning it  :)   But one of the things I wanted to try out was using the Silverlight WebClient capability to call a Controller action (vs. a web service, etc…).  I’m treating Silverlight as a UI presentation layer – and letting my Controller/Actions be the glue to my existing service layer/data layer.

I used Scott Guthrie’s blog post as a guide to using the WebClient capability:

http://weblogs.asp.net/scottgu/pages/silverlight-tutorial-part-3-using-networking-to-retrieve-data-and-populate-a-datagrid.aspx

A few steps:

The Action – using XmlResult

I wanted the data returned from the Action to be xml.  Luckily, the MVCContrib includes a ‘XmlResult’ (ActionResult).  If you download the source you can see what it is doing.  A brief description: “…Action result that serializes the specified object into XML and outputs it to the response stream.”  Just want I want

Here is a quick example of the action I’m using:

public XmlResult XmlSquadronStats(string SquadId)
        {
            IPilotStatsDao pilotStatsDao = DaoFactory.GetPilotStatsDao();
            var stats = pilotStatsDao.GetAllPilotSummariesBySquad(SquadId);
            return new XmlResult(stats);
        }

 

Silverlight

With Silverlight, you cannot add a ‘non-Silverlight assembly’  – so in the above, I’ll be returning a List<PilotStats> – but I can’t just include the ‘PilotStat’ class in my domain object in silverlight.  That isn’t a bad thing however, as it will help me layer my Silverlight application.  So my first step is to create a new class, which I call PilotStat (see that above article by Scott Gu, I’m just taking that same concept and applying it here).

public class PilotStat
    {
        public string PilotName{get;set;}
        public int Missions{get;set;}
        public int Flights{get;set;}
        public int Kills{get;set;}
        public int Deaths{get;set;}
        public int Landed{get;set;}
        public int GroundTargets{get;set;}
        public int Crashes{get;set;}
        public int Bailed{get;set;}
        public int Captured{get;set;}
        public int ShotDown{get;set;}
        public int TanksDestroyed{get;set;}
        public int ShipsDestroyed{get;set;}
        public int Points{get;set;}
    }

Next, I want to work with my Page.xaml – to keep it simple, I want to use a querystring to pass to the page to determine which ‘squadrons’ data I want to load in the view.  This is the part of Silverlight I do like – it’s interaction with the underlying page.  So first I want to validate there is a querystring key/pair being used:

if (!System.Windows.Browser.HtmlPage.Document.QueryString.ContainsKey("SquadId"))
            {
                Status.Text = "Please provide SquadId";
            }

Next, I’m adding some code to make it easy to deploy later (this is really simple example!)

else
            {
                string squadId = System.Windows.Browser.HtmlPage.Document.QueryString["SquadId"];
                try
                {
                    Uri uri = Application.Current.Host.Source;
                    string host = uri.Host;

                    string statsUrl = string.Format("http://{0}/ForgottenWars/Squadron.mvc/XmlSquadronStats?SquadId={1}", host, squadId);
                    Status.Text = statsUrl;
                    WebClient client = new WebClient();
                    client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
                    client.DownloadStringAsync(new Uri(statsUrl));
                }
                catch (Exception ex)
                {
                    Status.Text += ex.Message;
                }
            }

Lastly, I want to display these results in the Datagrid:

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            DisplayStats(e.Result);
        }

        void DisplayStats(string xmlContent)
        {
            XDocument xmlStats = XDocument.Parse(xmlContent);
            var stats = from stat in xmlStats.Descendants("GetAllPilotSummariesBySquadResult")
                        select new PilotStat
                        {
                            PilotName = (string)stat.Element("PilotName"),
                            Missions = (int)stat.Element("Missions")
                        };
            PilotStatsGrid.ItemsSource = stats;
        }

I’m happy to report that this works well  :)   I developed it on my Vista laptop with IIS 7 and was able to easily deploy the clientbin to my hosted IIS 6 server.

Although not rocket science here, I like the idea of being able to resuse my existing mvc architecture and adding this Silverlight UI on top of it. 

Feel free to send me any feedback on this approach!

MvcContrib – Grid – a diamond in the rough

July 22nd, 2008

The MvcContrib is a community driven code repository for asp.net mvc.  I’m quite impressed and hope to see more cool stuff.  The source code is available on codeplex. (check out the additional documentation here)

A couple of items from the contrib that I’m looking into:

1. UI – Grid

2. Pagination

There is some easy to read documentation on the grid as well as how it works with paging.

As you may know from reading my blog, I’m a big fan of jQuery with the asp.net mvc architecture.

The MvcContrib plays well with my jQuery table.

For example, adding sortable headers:

I use a common class for my ‘tablesorter’ jQuery implementation.

Let’s take an example from the hobby gaming website:

 

<% Html.Grid<FSData.TerritoryCaptured>(
    ViewData.Model.TerritoryCaptured.AsPagination(Int32.Parse(ViewData["page"].ToString()), 2),
    new Hash(empty => "No data available", id=>"terr1", @class=>"tablesorter",  style => "width:600px"),
    column => {
        column.For(p => p.TerritoryName, "Territory");
        column.For(p => p.CapturedBy).Formatted("Captured By: {0}");
        column.For(p => p.DateCaptured.Value.ToShortDateString(), "Date").CellCondition(p => p.DateCaptured.HasValue);
        column.For("Custom Column").Do( p => {%>
            <td>a custom column</td>
        <%});
    }
    ); 

     %>

In the above markup, I’ve tried to use some of the features in the documentation link above.  Keep in mind, all of this supports intellisense as you build the grid!  A few notes:  I use the @ with @id and @class – those just make sure it’s written literally (there is a conflict with keyword ‘class’ of course!)

Using the jQuery tablesorter, I’ve marked this with the class ‘tablesorter’.  (It’s easy to apply styles the grid – as it outputs a table)

In my javascript, simply add the $(“#terr1″).tablesorter(); and you have tablesorting!  You can leave out the ‘id=>”terr1″‘ and use $(“.tablesorter”).tablesorter(); (instead – this will apply the tablesorter to any class marked with ‘tablesorter’ using the jQuery css selector logic).

Sorting can be done on the server, for example:

<% Html.Grid<Person>( "people", column => { column.For(p => p.Id).Heading(() => { %> <th><a href="/People/List?orderby=id">Id</a></th> %>}); column.For(p => p.Name); column.For(p => p.Gender); column.For(p => p.RoleId); } ); %>

jQuery has a pagination ‘addin’ to the tablesorter that I use, however it’s client side only. 

I look at it this way: if I want client side functionality with my tables – it’s easy to use jQuery to achieve this.  However, in situations where I want server side paging or sorting, this grid provides a good start on providing that functionality.

I also think this grid will cut back on the amount of html I will write and yet still have absolute control on what is generates!  :)

Another reason to like jQuery…

July 18th, 2008

Flexigrid – ‘Web 2.0 Grid Made Easy’

Very well done – and of course with the ease and simplicity of jQuery…

This one deserves a 5 star bump :)

Ankhsvn 2.0

July 18th, 2008

I’m installing Ankhsvn 2.0 today – I had tried earlier versions but the new one looks good.  Here are some screenshots.

Check out the 2.0 final release comments to learn more of the changes, features, etc…

Shifting directions…

July 17th, 2008

Sometimes a refactor can be painful, but there is a light at the end of the tunnel, especially when you know the refactor will be a good move.

I really enjoyed working with Spring.NET but decided to shift to a simplier* model (Sharp Architecture).  A positive is that my code was separated well enough that the impact was minor.  (when I say ‘simplier’ – most that I’m only using a small subset of Spring.NET – NHibernate session management/Transactional management/Dao injection into my controllers)

One move led to another, and I made the jump to NHibernate 2.0.  While I was frustrated at being able to find the installer for NHQG 1.9 (there is one for 1.8 with NH 1.2) – I realized that the NHibernate direction is moving to NHibernate.Linq… so, hey, let’s try it out.

Let’s compare:

ICriteria:

            ICriteria crit = Session.CreateCriteria(typeof(EmployeeQuerySet))
                .Add(Expression.Like("LastName", lastName, MatchMode.Start));
            return crit.List<EmployeeQuerySet>();

 

NHQG:

return this.FindAll(Where.EmployeeQuerySet.LastName.Like(lastName, MatchMode.Start), OrderBy.EmployeeQuerySet.LastName.Asc);

 

NHibernate.Linq:

                        var query = from emp in Session.Linq<EmployeeQuerySet>()
                        where emp.LastName.StartsWith(lastName)
                        orderby emp.LastName ascending
                        select emp;

I personally like the Linq syntax because I’ve been using it since it was available to replace all my collection delegate calls.

So far so good on the refactoring…  :)

(By the way, I really haven’t seen the value of something like EF or Linq to SQL when I have the power of NHibernate and NHibernate.Linq)

Learn more about NH 2.0 here

ASP.NET MVC Preview 4 Released

July 16th, 2008

Get it here:

http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=15389

 

Some blogs on it:

Phil Haacked:

http://haacked.com/archive/2008/07/16/aspnetmvc-codeplex-preview4.aspx

Scott Hanselman (his post shows an example of the ajax helpers)

http://www.hanselman.com/blog/ASPNETMVCPreview4UsingAjaxAndAjaxForm.aspx

Application Layering

July 16th, 2008

A good layering diagram:

In my asp.net mvc I skipped the service layer and the actions were marked with Spring.NET [Transaction] attributes.

After a response from Mark Pollack at Spring.NET I can see that this is probably not such a good idea.  He mentioned instead of using the service layer

(ie. a transactional service layer, WCF, or web services).  In my case, a transactional service layer would fit well.

That being said, my refactoring would be to move my calls to the Dao from the Controller->Actions into a service layer.  This would provide a better separation of concerns as well as decouple the controller from the dao – allowing me to use another UI technology (ie. Silverlight, or WPF/WinForm) which would utilize the same service interfaces. 

This picture is worth a 1000 words:

One question I have is the box ‘Domain objects’ – I know it’s not maybe the best approach, but I have used my POCO objects as my domain model.

This architecture would possibly require me to use a more ‘disconnected’ approach with NHibernate ?

ScottGu on the upcoming Preview 4 of MS MVC

July 14th, 2008

http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx

Looks like the next release will be adding features – not the overall core API changes like we saw in Preview 3.

Some items: OutputCache attributes over actions – this is nicely done!  I’m looking forward to it.  Also, the error handling capabilities with friendly messages, handling certain exceptions, etc.. is going to really help as well!

Security: a new ‘Authorize’ attribute will be added as well as Account management (gee, I built this one already – but sure it nice to be a part of the project!)

Glad to see them adding in some cool functionality!