NFL Picks: 08-09 Week 16 Results and Week 17 Picks

posted on 12/26/08 at 11:21:35 pm by Joel Ross

It's the final week of the regular season, and it's Christmas week! Awesome combo. Anyway, on to last week's results.

Results Summary

And now it's time for the last regular season picks for the season!

Should be a good week. Playoff match ups will be finalized by Sunday night, and then the real season starts!

Tags: | |

Category: Football

Leave a comment


 

NFL Picks: Week 15 Results and Week 16 Picks

posted on 12/19/08 at 12:40:11 am by Joel Ross

This is a bit late, but I made my picks long before the game started tonight!

Results Summary

On to this week's picks

Check back next week for results, and my final regular season picks.

Tags: | |

Category: Football

Leave a comment


 

Balsamiq: Easy UI Mockups

posted on 12/11/08 at 08:59:55 pm by Joel Ross

About a week ago, I was finally to a point where I was ready to take on a new feature at TrackAbout on my own. Well, it was just one screen, but it was a fairly complex screen, so I was asked to come up with an idea of what I thought it should look like. In the past, I've done mock ups in the past, but before diving into the pain that is Visio, I decided to ask our team what we've used in the past.

Joey said he'd been happy with Balsamiq, so I decided to give it a look. I was immediately impressed. It was so easy to use, and much, much more intuitive than what I was used to. In less than an hour, I was able to create mock ups for my screen in 4 different states.

Then, when I needed to make updates the next day, it was as simple as importing an XML document to get back to where I was the day before. Oh yeah. Did I mention I did this all online in a browser? Yeah - no software to install and all in the browser. They have lots of controls you can use, and it's all drag and drop. They've even added keyboard shortcut support, so things like copying, pasting and selecting work just like they would in a desktop application.

Since I can't really show what I actually designed, I spent 5 minutes creating a simple mock up of - guess? - a bracket, much like we have on Tourneytopia. Here's what I came up with:

BalsamiqScreen

It's all drag and drop, and you can quickly get a realistic mockup going in very little time. It's definitely a tool I will be using in the future when I need to layout new user interfaces.

Tags: | |

Category: Software

4 comments


 

NFL Picks: 08-09 Week 14 Results and Week 15 Picks

posted on 12/11/08 at 12:15:31 am by Joel Ross

We have a big release we're pushing out, so this'll be short and sweet.

Results Summary

And moving right along: this week's picks.

Check back next week for results and more picks. Only two regular season weeks left!

Tags: | |

Category: Football

Leave a comment


 

Steve McConnell's Software Estimation

posted on 12/08/08 at 11:45:04 pm by Joel Ross

Over the past couple of months, I've been participating in a virtual book club. We had been reading Steve McConnell's book on Software Estimation, and having weekly discussions about the chapters we've been reading. The pace has been reasonable - two or three chapters a week, which equates to about 40 pages of reading per week. Now that we've moved on to the next book, I figured it was time to finally post about the first book.

Mike Eaton was the organizer of the book club, and it's been a great experience thus far. Usually, I'll read through a book, but not have a way to find out what others are thinking. On occasion, I'll come across a blog post reviewing the whole book (kind of like this one!), but I've never really had anyone to discuss the ideas in the book with. By reading the book as part of the book club, I got the chance to just that on a weekly basis.

I think we all started out thinking this was going to provide "The Answer" to how estimates should be done. In reality, there are no silver bullets, and if that's your reason for reading the book, you'll walk away disappointed. The book is more of an encyclopedia of techniques to use during estimation, giving the pros and cons of each, but never really gives an opinion about what the best way is. I guess that makes sense when you consider that every situation is different and unique.

There was one good takeaway from the book that we all kept coming back to: The Cone Of Uncertainty. This essentially says that early on in a project, your ability to accurately estimate a project is extremely low. The further you get into the project and discover the previously unknowns, the more accurate your estimates will be. This makes logical sense when you think about it, but sometimes it takes having it laid out in front of you to truly grasp it. The book also put a number to that uncertainty. At the cone's widest point, there's a 16X difference between the two end points, meaning that any estimate you give early in a project could be 4 times over or under the actual outcome. That's very significant, especially if you're used to putting numbers on paper at that point and committing to dates! It then shows that as you move further in design and nail down what needs to be done, that you can get to a point where your variability can get down to around 25%, which is much more acceptable to start moving forward with commitments than 400%!

Overall, I think the book was worth the read, although I could have done without most of the second section. Reading part one, the first chapter or two in part two, and then the last two chapters would have been a good approach. Those middle chapters were repetitive and drawn out - they went over different estimation techniques, discussing where they apply and where they don't. I think if I was in an estimation situation, I could use that middle section for guidance, but just reading them through didn't do much for me. Still, it was a good book and worth my time.

Now, we're moving on to Working Effectively With Legacy Code, a book I'm really looking forward to discussing!

Tags: | |

Category: General, Development

1 comment


 

Grand Rapids Tech Lunch Recap

posted on 12/03/08 at 10:35:56 pm by Joel Ross

This past Monday, we had our 7th GR Tech Lunch, and had some great guests: Ben Gott and Rick DeVos. They both did a great job, and we had our biggest turnout since we started. I didn't count, but we had somewhere between 30 and 40 people.

Ben and Rick did a great job explaining how they got started, how they got in touch with each other, and what they're working on together. Then they talked a bit about the lessons they've learned along the way and answered lots of questions specifically about what they're doing and starting a business in general.

Ben offered up his biggest lesson learned, and it really struck home for me. he said, "Don't build software you don't use." It seems so obvious, but you'll be much less effective building something that you don't want to use. And it's not just the overall software; Remember that on features too, especially early in development. Maybe once your application is more established and has a solid customer base, you can start to add features you wouldn't use because it has a bottom line implication. Early in the project though, when you don't have a clear view of where revenue will come from, build what you will use. It sees some so obvious now.

Anyway, it was a thrill to have those two speak, and I wanted to thank them publicly. For those that don't know Ben and Rick, I'll give you some background (as best as I know it). In 2005, Rick and a few of his friends came to NuSoft to get help with an idea they had: build a site for independent film makers and their fans. The result: Spout.com. Ben also came to NuSoft to help build out his idea: build a site where independent music artists could sell directly to their fans. The result: Indistr.com.

Sense a theme? I started to: Find a group that provides something others need and allow them to connect directly with those people. Apparently they did too, because after those two things, they joined forces. A while later they launched TheCommon.org, a site focused on community members relating their needs and allowing other community members to meet those needs. It's a great idea, and it sounds like they are getting pretty good traction, at least in the Grand Rapids area. I definitely plan to recommend it to my church!

Anyway, if you were at the lunch and I didn't get to say hi, sorry! Leave a comment though and let me know you were there. Also, next month, we have another great speaker lined up, but I'll leave that announcement for the Grand Rapids Tech Lunch site. So, if you're interested in attending, make sure to subscribe to the RSS feed or check it often. For this last one, we used the comments as the reservations, and filled up fast!

Tags:

Category: Develomatic, GR Tech Lunch

Leave a comment


 

NFL Picks: 08-09 Week 13 Results and Week 14 Picks

posted on 12/03/08 at 08:58:37 pm by Joel Ross

What a crazy weekend. I ended up sick most of Saturday and Sunday, so only watched a little bit of one game. But I still have results.

Results Summary

On to next week's picks.

Check back next week for results and more picks.

Tags: | |

Category: Football

Leave a comment


 

NFL Picks: 08-09 Week 12 Results and Week 13 Picks

posted on 11/26/08 at 10:43:03 pm by Joel Ross

Yet another week goes by with no technical content. But at least I have my picks!

Results Summary

There's very little better than Thanksgiving day football. Of course, it always includes the Lions, so there is a downside

Check back next week for results and more picks. And happy Thanksgiving!

Tags: | |

Category: Football

Leave a comment


 

NFL Picks: 08-09 Week 11 Results and Week 12 Picks

posted on 11/20/08 at 08:05:23 pm by Joel Ross

Another week of being just about too busy, but I had to get my picks up, right?

Results Summary

On to this week's picks.

Check back next week for results and more picks.

Tags: | |

Category: Football

Leave a comment


 

NFL Picks: 08-09 Week 10 Results and Week 11 Picks

posted on 11/13/08 at 08:07:23 pm by Joel Ross

I almost forgot to get these posted before the game tonight. Getting up and running in a new job is always a time consuming proposition, but I'm getting there!

Anyway, here's last week's results. I did pretty good - except over/under, where I was horrible!

Results Summary

And right into this week's picks.

Check back next week, where maybe I'll get the picks up at a decent time.

Tags: | |

Category: Football

Leave a comment


 

NFL Picks: 08-09 Week 9 Results and Week 10 Picks

posted on 11/05/08 at 10:46:58 pm by Joel Ross

Well, no work this week, but somehow it's been busier than just about any week this year! It's sad when you look forward to getting back to work so you can stop working so much!

Anyway, I had a pretty good week last week, and it made me above 50% for all three categories - picks, spread picks and over/under. Not bad.

Results Summary

On to the reason this is being posted on Wednesday instead of Thursday - a Thursday night game!

Check back next week for results and more picks.

Tags: | |

Category: Football

Leave a comment


 

NFL Picks: 08-09 Week 8 Results and Week 9 Picks

posted on 10/30/08 at 08:00:00 pm by Joel Ross

This week has been just as busy as last week, so another quick hit. But it was a rather decent week. If I'd put money on every game (picking, spread and over/under), I would have had over a 7% return in one week. That's pretty good.

Results Summary

Here's my picks for this weekend.

Check back next week for results and more picks!

Tags: | |

Category: Football

Leave a comment


 

Transitions

posted on 10/28/08 at 11:16:05 pm by Joel Ross

About a month ago, I came across a post from Joey Beninghove that caught my attention. Actually, it was a tweet of his referencing his blog post. Anyway, it was about a job opening where he works, and what caught my eye was that it was a telecommuting position. As some of you may know, I enjoy working in the The Dungeon when I can, and the opportunity to make it permanent was very appealing to me. So I decided to contact him to get some more information, and ultimately decided to apply.

Fast forward a month. Last Friday, I accepted an offer from TrackAbout, and will start there on November 10th. This week, I turned in my notice at RCM. I'm extremely excited about the opportunity. Ironically, I could copy the changes Joey posted about when he started at TrackAbout and use them as my own. This is a pure software development job - no more consulting for me, which is a scary prospect. All I've done throughout my career is consulting, so it's a big change for me. But I've felt the tug to "settle down" and get deeper into the code, and learn what it means to write maintainable code. Now I'll get that chance.

I will definitely miss the time I've spent at Sagestone/NuSoft/RCM. I've been there for over 6 years, and learned just about everything I know about software development while I was there. I've had a chance to help change the way software is developed there, and I've worked on a few very cool projects. Me leaving has more to do with what TrackAbout offers than it does with what RCM lacks. I'll definitely miss working with the people at RCM, but the good news is that it's easy to stay in touch with them through Twitter, Facebook, etc. so I'm not really worried about losing touch. Still, it's not the same as working with them every day.

Anyway, I'm very excited to get started, and looking forward to working at home. Plus, how many people can say they found their job on Twitter?

Category: Personal, RCM Technologies, TrackAbout, Inc

2 comments


 

Recognizing and Eliminating Your Mistakes

posted on 10/27/08 at 12:12:10 am by Joel Ross

As I stated in my last post, I've been reading up a bit on code reviews. I didn't touch on the last part of the book, which finishes with a discussion of Capability Maturity Model Integration, Team Software Process and Personal Software Process.

When I was at Crowe, I was a part of the review process to move from CMM level 1 to CMM level 2. For the most part, the ideas were good, but the implementation seemed overly documentation-intensive. Not that documentation is necessarily a bad thing, but there was so much administration that I didn't see how it could work and still allow us to be competitive.

Anyway, the part of the discussion that caught my attention was the idea of using a personal checklist, much like the checklist you'd use to perform a code review. In order for you to become a better developer, you need to know where you make mistakes. I could sit here and write out all of the ways I think I screw up, but that's just my gut speaking. It's not rooted in fact. The book's recommendation is that you should keep track of all of the mistakes you  make and categorize them. By making yourself aware of the types of mistakes you commonly make, you'll start to avoid making them, and then you can take that off your list. And until you fix that type of issue, you'll at least be aware of it, so as you review your own code, you can look for it.

I think I'll start trying to do this - just a very quick and dirty list, and at the end of the day, I'll categorize them. By making them visible, hopefully I'll start thinking about them as I write code. At the very least, it'll give me something to look at as I review my own code before I check it in.

Of course, that's another benefit of keeping a personal checklist - if you're doing code reviews, you can (and should) share that with your reviewers, because it gives them something to focus on - specific types of mistakes that you know you commonly make. Remember, it's not a bad thing for your team to know your weaknesses. Ultimately, you share the same goal - build the highest quality software possible. It's in the best interest of the whole team to help each other improve, and the best way to do that is to know where you need to improve. And in the mean time, it's good to have someone else looking over your shoulder.

Tags:

Category: Development

1 comment


 

Code Reviews

posted on 10/24/08 at 12:27:43 am by Joel Ross

I've been reading through a free book I got a while back - Best Kept Secrets of Peer Code Review - and it's actually a pretty good read. It is a rather dry read, but there's some good information in there. And in case you were wondering, you can get the book for free as well. Just follow the above link.

Anyway, I should note that there's definitely a reason the book is free - it's findings and advice directly correlate with the feature set of their core product - Code Collaborator. Conveniently, there's also a 20-page ad for the software in the book. The software is around $500 per seat, so you can see why it's worth giving away the book. The advice in the book is definitely slanted toward what their own tool does. The question is whether the software was built around the results of the research (of which the book has plenty), or if the research was hand picked to support what their software does. I don't know that answer, but regardless, there's some interesting information in the book - and since it's free, I think it's worth the read.

There are definitely some things I question in the book - for example, it essentially assumes that everyone is doing code reviews and is reviewing every single line of code. That's not something I've ever seen. Regardless of some of those type of issues, there are a few takeaways that I'd love to get a chance to use on my own projects.

To be honest, I haven't been a part of that many code reviews on my projects. When I was at Crowe, we did code reviews on an internal product I was a part of. We didn't review every line - not even close. We reviewed code for key pieces of the system, as well as reviews for new developers. Crowe typically hires (or at least used to hire) a lot of fresh developers - people right out of college - so reviewing their code was important to make sure they were progressing and doing things the way the project expected. At that time, a lot of that was my code. Crowe was my first job out of college. Since we were all relatively inexperienced, we didn't really know much about what we were supposed to be doing. It was more of a walkthrough of the structure of the code rather than a true analysis looking for specific types of issues. Looking back, I don't remember finding many defects in the code, and the ones we did find were more along the lines of code flow and coding standards rather than actual bugs. Still important, but if I had it to do over, I think it would be much more productive.

We've done code reviews on a few of my projects at Sagestone/NuSoft. Based on how we did them, I don't think they were all that productive either, because we didn't have a solid goal for why we were doing reviews. We needed to do a review, so we did one. If I had to pick a goal, it was more to ensure that the code lived up to coding standards, rather than reviewing the code for correctness. It's important to be consistent, but there are easier, less time intensive methods to verify that. Our time would have been better spent looking at the actual logic contained in the code rather than the structure of the code. But hindsight is 20/20, right?

Anyway, there's a few things the book highlights that I found interesting.

That's definitely a shift in how I've done code reviews in the past. For the most part, the prep for the code review itself only consisted of a brief review of the code, and the assumption was that the deep dive into the code would happen in the two hour meeting. It actually makes sense that it should be the opposite - the deep dive should happen ahead of time, and the meeting (if it even needs to happen) should just be a summary of what was already found.

Interesting thoughts, really. But I still wonder how many people are actually doing code reviews. So, are you doing code reviews? Are they effective? What makes them that way?

Category: Development

4 comments


 

NFL Picks: 08-09 Week 7 Results and Week 8 Picks

posted on 10/23/08 at 08:00:00 pm by Joel Ross

It's been a busy week (again), but here's last week's results.

Results Summary

On to this week's picks.

Check back next week for more results and more picks.

Tags: | |

Category: Football

Leave a comment


 

NFL Picks: 08-09 Week 6 Results and Week 7 Picks

posted on 10/16/08 at 08:00:00 pm by Joel Ross

I'm sitting in a hotel room in Orlando, but I still wanted to get these out there. So here they are! Results from last week:

Results Summary

And on to picks for this week:

Check back next week for more results and more picks

Tags:

Category: Football

Leave a comment


 

Per Request Activation With Ninject

posted on 10/14/08 at 08:00:00 pm by Joel Ross

As I've started to look into NHibernate and how to manage the NHibernate session, I quickly came across the "session per request" model as the recommended (or at least most popular) approach. I initially started out with a context-based storage and eventually refactored the code to be much simpler - the refactoring was very similar to what I did in my last post. By allowing my IoC container to manage the session's lifecycle, I no longer had to worry about it, and removed my reliance on a static class. As a result, I can easily change the session code without affecting any of the code that uses it.

When I started down this path, Nate Kohari warned me that Ninject's  OnePerRequestBehavior didn't seem to be working. He mentioned that he wondered how the Castle team did it, so I started digging. It turns out they did it with a combination of a life cycle management class (their equivalent of behaviors in Ninject) and an HTTP module. With that idea in mind, I dug into Ninject's code to see if I could get something working.

In the end, I got it working, but it's not a generic, "drop in" solution - it requires the registration of an HTTP module in your web.config file, so it's not as seamless as what Nate was going for. But it works, at least for my case. I created a class called CustomOnePerRequestBehavior that looks eerily similar to the original OnePerRequestBehavior! The main difference comes in the Resolve method. Rather than trying to handle the EndRequest event directly (which never actually fires) it just registers itself with the HTTP module:

   1:  public override object Resolve(IContext context)
   2:  {
   3:    Ensure.NotDisposed(this);
   4:   
   5:    lock (this)
   6:    {
   7:      if (ContextCache.Contains(context.Implementation))
   8:        return ContextCache[context.Implementation].Instance;
   9:   
  10:      ContextCache.Add(context);
  11:      context.Binding.Components.Get<IActivator>().Activate(context);
  12:   
  13:      RequestModule.RegisterForEviction(this);
  14:      return context.Instance;
  15:    }
  16:  }

This calls a static method on my request module:

   1:  internal static void RegisterForEviction(CustomOnePerRequestBehavior manager)
   2:  {
   3:    HttpContext context = HttpContext.Current;
   4:   
   5:    IList<CustomOnePerRequestBehavior> candidates = (IList<CustomOnePerRequestBehavior>)context.Items[PerRequestEvict];
   6:   
   7:    if (candidates == null)
   8:    {
   9:      candidates = new List<CustomOnePerRequestBehavior>();
  10:      context.Items[PerRequestEvict] = candidates;
  11:    }
  12:   
  13:    candidates.Add(manager);
  14:  }

This basically stores a list of items that should be taken care of at the end of a request, and stores it in the context.

Beside the static method, the request module also registers to listen for the EndRequest event. When that event fires, it grabs the list of items that should be taken care of at the end of the request, and calls the CleanUpInstances method on the stored instance (that was the other change to the original OnePerRequestBehavior - CleanUpInstances is now internal instead of private):

   1:  void context_EndRequest(object sender, EventArgs e)
   2:  {
   3:    HttpApplication application = (HttpApplication)sender;
   4:    IList<CustomOnePerRequestBehavior> candidates = (IList<CustomOnePerRequestBehavior>)application.Context.Items[PerRequestEvict];
   5:   
   6:    if (candidates != null)
   7:    {
   8:      foreach (CustomOnePerRequestBehavior candidate in candidates)
   9:      {
  10:        candidate.CleanUpInstances();
  11:      }
  12:   
  13:      application.Context.Items.Remove(PerRequestEvict);
  14:    }
  15:  }

And that's pretty much it. To use it, I can have a line like this in my module:

   1:  Bind<ISession>().ToProvider<SessionProvider>().Using<CustomOnePerRequestBehavior>();

I should note that I didn't really write any of my own code here. I used a combination of what the existing OnePerRequestBehavior already does, adding in what the Castle team did. Regardless of where the code came from, by doing this, I can now easily achieve session per request, which is what my goal was in the first place.

Tags: | |

Category: Development, C#

Leave a comment


 

An Unexpected Benefit of Using an IoC Container

posted on 10/13/08 at 12:57:22 am by Joel Ross

In the past few weeks, I've basically come full circle on the usage of dependency injection frameworks and Inversion of Control containers. Back in March, I was questioning whether one was necessary, since I hadn't seen a need to do anything so complex that I couldn't wire it up by hand.

It turns out there's a bit of a chicken and egg thing going on here. I didn't need a container because my software wasn't complex enough to warrant one, and my software wasn't complex enough because I didn't have a container to manage that complexity.

That changed a few weeks ago, when I started down the road of working with repositories in conjunction with MVC. That gave me an opportunity to start from the ground up with a container. As a result, wiring pieces together became trivial. That, in turn, allowed me to build interactions between components that before would have been very difficult to manage.

But that's not what this post is about. As I started to get into using my container, I discovered a side benefit I hadn't considered before. I'll demonstrate it through a refactoring that I went through to get my code in better shape. First up, how the code started out:

   1:  public static class MyAppContext
   2:  {
   3:    public User CurrentUser
   4:    { 
   5:      get
   6:      {
   7:        return HttpContext.Current.Items["CurrentUser"] as User;
   8:      }
   9:      set
  10:      {
  11:        HttpContext.Current.Items["CurrentUser"] = value;
  12:      }
  13:  }

It's a simple example that maintains the current user for the duration of an HTTP request. Nothing fancy, but this type of model gets used a lot. At first glance, it doesn't look too bad. But there's issues here. It's static, which means I can't do much to test it (or code that relies on it). And even if I refactored it so it wasn't static, there's that HttpContext.Current statement in there, which would still make it un-testable (or at least difficult).

The other problem is that this class has multiple responsibilities. I never saw it before, but now that I've noticed it, it sticks out like a sore thumb. This class is responsible for not only giving access to the current user, but also how that current user is stored - essentially, this class is managing it's own lifecycle. That's a violation of SRP.

So, we take a two-pronged attack to fix it. First, make it non-static. That's trivial, so I won't show that. Second, inject the storage into the class. Come up with a simple interface for storage:

   1:  public interface IStorage
   2:  {
   3:    public void Set<T>(string key, T value);
   4:    public T Get<T>(string key);
   5:  }

Then, create an implementation that uses HttpContext to achieve what we had before:

   1:  public class ContextStorage : IStorage
   2:  {
   3:    public void Set<T>(string key, T value)
   4:    {
   5:      HttpContext.items[key] = value;
   6:    }
   7:   
   8:    public T Get<T>(string key)
   9:    {
  10:      return HttpContext.Current.Items[key] as T;
  11:    }
  12:  }

Then we change the original MyAppContext to use the interface, rather than HttpContext directly:

   1:  public class MyAppContext
   2:  {
   3:    private IStorage _storage;
   4:   
   5:    MyAppContext(IStorage _storage)
   6:    {
   7:      _storage = storage;
   8:    }  
   9:   
  10:    public User CurrentUser
  11:    { 
  12:      get
  13:      {
  14:        return _storage.Get<User>("CurrentUser");
  15:      }
  16:      set
  17:      {
  18:        _storage.Set<User>("CurrentUser", value);
  19:      }
  20:  }

This is pretty good. Now, the class delegates to another class to handle how it's data is stored, and I could create an implementation of IStorage that uses a dictionary internally and pass it to MyAppContext for testing purposes, without ever changing my code.

Now, the next question. How do you manage MyAppContext now that it's not static? How do you create one? How do you keep track of it throughout it's duration? Who is responsible for it's lifecycle? All valid questions, and all difficult to handle manually. But if I'm using an IoC container, I can let the container manage the life cycle for me. And it does it outside of the class, so MyAppContext becomes even simpler, because it can use normal techniques for storage:

   1:  public class MyAppContext
   2:  {
   3:    public User CurrentUser { get; set; }
   4:  }

That was definitely a long-winded explanation of how I got from a static, HTTP-based class to your every day run of the mill class, yet still get the same functionality with no real extra cost. Well, no cost except the IoC container implementation. Which brings me full circle, and back to what the title of this post alludes to: Using an IoC container allows me to easily implement and use classes that are ignorant of their surroundings. When I first started down the IoC path, I knew the benefits I expected - being able to program against interfaces and let my container figure out how to inject the actual implementations. But what I didn't expect was to be able to rely on the container to manage the lifecycle of my objects and allow me to write code the way I normally would.

Tags: | |

Category: Development, C#

4 comments


 

NFL Picks: 08-09 Week 5 Results and Week 6 Picks

posted on 10/09/08 at 08:00:00 pm by Joel Ross

I didn't get to watch a single minute of NFL football this weekend. That was a bit disappointing, but life goes on. Anyway, here are the results from last week.

Results Summary

On to picks for this week. It's been a busy week, so I haven't had much time to follow much NFL news.

Check back next week for the results and more picks.

Tags: | |

Category: Football

Leave a comment


 

Query Objects and the Specification Pattern

posted on 10/07/08 at 10:55:44 pm by Joel Ross

The other night, I had an eye opening moment when I finally understood how I could use query objects to allow me to use a generic repository, yet still be able to have re-usable queries. But one thing I didn't quite get was how this related to the Specification pattern. The samples I found (including the one I linked to) all used the term Specification, but that wasn't how I understood the specification pattern to work.

But just by adding one method to the base class, it (again) became clear how the two are related:

   1:  public bool IsSatisfiedBy(T candidate)
   2:  {
   3:    return SatisfyingElementsFrom(new[] { candidate }.AsQueryable()).Any();
   4:  }

By adding this, you can now pass an entity to it, and determine if that entity satisfies the specification. As a result, I've renamed my base class to SpecificationBase<T>, and can now use them for validation purposes as well.

Now, the next question. Does this violate the Single Responsibility Principle? At first glance, I thought it did, because it's used to do two different things: query and validate. But taking a closer look, I don't think it does. How it's used externally is different than what it does internally - which is check that a collection of entities (even if the collection is only one element) satisfies a given specification. More to the point, it's single reason for change would be if there was a change to how it determines that an entity meets the specification. That isn't related to querying or validating at all - that's above this layer.

Of course, I could be wrong. In your opinion, does this violate SRP? If so, how would you fix it?

Tags: | |

Category: Development, C#

1 comment


 

The Repository Pattern – I’m Sold!

posted on 10/05/08 at 08:59:10 pm by Joel Ross

Lately, I've been playing with NHibernate and the Repository pattern - and struggling with it a bit. I understand the concept, but it's the implementation that's been bothering me. I was questioning whether to use one repository, or to have many - essentially one per entity. You can see me questioning it a bit in the Entities And Repositories Discussion I posted a while ago, where I asked Nate Kohari whether he used one repository or many. Here's the relevant part of that conversation. I've filtered it quite a bit to capture our back and forth.

RossCode: nkohari: do you have one repository or multiple repositories?
nkohari: RossCode: lately i've been using one
nkohari: but you can only get away with that in some cases
RossCode: nkohari: how do you handle custom queries? Pass in ICriteria?
nkohari: yeah, in the past i have, but lately i've moved to linq for nh
nkohari: so it's all Expression<Func<T, bool>>s
RossCode: nkohari: but then aren't your queries and how you query data in your controllers now?
nkohari: RossCode: touche ;)
nkohari: chadmyers was just talking about that
nkohari: he suggests creating query objects
nkohari: which is actually a very good idea

I didn't have a very good understanding of NHibernate at the time, and I certainly didn't get what he meant by query objects. Plus, it got lost in the middle of much larger conversation.

Fast forward to this past week. I was adding NHibernate to a project, and struggling with the same thing. I had an IRepository<T> that I was working against in my controllers. Then I had actual implementations like CustomerRepository, OrderRepository, etc. But when I needed to do something non-generic (like get a list of customers by a non-key id, like LastName), it quickly fell apart. Now my CustomerRepository had a method called GetCustomersByLastName. How do you use that method when you are working against IRepository<T>? Well, the first and obvious solution is to extract another interface - ICustomerRepository - and reference that in the controller. But that quickly gets overly complex.

So I went back to the tribe, and asked for some advice. I laid out what I was running into, and Nate pointed me to a blog that has information about using query objects. Once I saw it, it was so obvious! But it takes seeing it to really cement the idea. I immediately added it, and within an hour, my code was greatly simplified and much more generic. Not to mention easier to maintain in the long run.

So what exactly did I do? Well, I removed a lot of code. I had a base repository class that I removed. I had three or four custom repositories (OrderRepository, CustomerRepository, etc.) that I removed - and there would have been more of those if I wasn't so early in the development process.

I also added some code. I added a single Repository implementation, and I added a QueryBase<T> class, to help me encapsulate my queries.

Let's start with the Repository class:

   1:  public class Repository<T> : IRepository<T>
   2:  {
   3:    private ISession Session { get; set; }
   4:          
   5:    public Repository(ISession session)
   6:    {
   7:      Session = session;
   8:    }
   9:   
  10:    public IQueryable<T> GetList()
  11:    {
  12:      return (from entity in Session.Linq<T>() select entity);
  13:    }
  14:   
  15:    public T GetById(int id)
  16:    {
  17:      return Session.Get<T>(id);
  18:   
  19:    }
  20:   
  21:    public void Save(T entity)
  22:    {
  23:      Session.SaveOrUpdate(entity);
  24:    }
  25:   
  26:    public T GetOne(QueryBase<T> query)
  27:    {
  28:      return query.SatisfyingElementFrom(Session.Linq<T>());
  29:    }
  30:   
  31:    public IQueryable<T> GetList(QueryBase<T> query)
  32:    {
  33:   
  34:      return query.SatisfyingElementsFrom(Session.Linq<T>());
  35:    }
  36:  }

Note that I'm also using Linq For NHibernate, but the part that is interesting is at the end - the last two methods. Each take a QueryBase<T> object. This object defines what query to run. For example, if I want to get customers by last name, I could create a CustomersByLastNameQuery that inherits from QueryBase<Customer>. We'll get to how to do that, but first, QueryBase<T>:

   1:  public abstract class QueryBase<T> 
   2:  {
   3:    public abstract Expression<Func<T, bool>> MatchingCriteria { get; }
   4:   
   5:    public T SatisfyingElementFrom(IQueryable<T> candidates)
   6:    {
   7:      return SatisfyingElementsFrom(candidates).Single();
   8:    }
   9:   
  10:    public IQueryable<T> SatisfyingElementsFrom(IQueryable<T> candidates)
  11:    {
  12:      return candidates.Where(MatchingCriteria).AsQueryable();
  13:    }
  14:  }

This defines the mechanics of query objects. The Repository calls SatisfyingElementFrom (for one) or SatisfyingElementsFrom (for many), and the MatchingCriteria is used to determine how the query is built. This makes encapsulating queries easy - just implement MatchingCriteria. Here's one to get customers by last name:

   1:  public class CustomerByLastNameQuery : QueryBase<Customer>
   2:  {
   3:    private string _lastName;
   4:          
   5:    public CustomerByLastNameQuery(string lastName)
   6:    {
   7:      _lastName = lastName;
   8:    }
   9:   
  10:    public override Expression<Func<Customer, bool>> MatchingCriteria
  11:    {
  12:      get { return cust => cust.LastName == _lastName; }
  13:    }
  14:  }

As you can see, implementing your own query is relatively easy. And since the original method returns IQueryable<T>, you can later filter the results further, group them, sort them, etc., and still get the benefits of delayed execution. For completeness, here's how you could call the repository:

   1:  IQueryable<Customer> customers = repository.GetList(new CustomerByLastNameQuery(lastName));

By doing the above, I now have exactly what I want: simplicity in my repositories, and the ability to encapsulate and control how my entities are queried.

Tags: | |

Category: Development, Software, C#

11 comments


 

NFL Picks: 08-09 Week 4 Results and Week 5 Picks

posted on 10/02/08 at 09:37:26 pm by Joel Ross

I didn't do too bad this week, honestly. 8-5 in picks and spread - I could live with that long term! It's the over / under that killed me this week.

For those who've been around a while, last year, I used to post about how much money I would have won or lost based on a $10 bet per pick (actually $30 per pick - picking the outright winner, the winner against the spread, and the over/under). At some point, I started comparing that to how I would have done against putting that same amount of money ($360-$480 per week) into an index fund. I still have the fund stats, so I figured with all of the financial news lately, I'd see how things looked. My theory (at the end of the season) was that the market typically goes up, so over time, investing in the market would be better. I still think that, but this proves that a year isn't long enough - or at least this year isn't. At the end of last year, I would have had $7,742.69 (after betting $8,010). Had that same amount been invested on a weekly basis in an index fund, the value (as of closing today) would have been $5,559.47. That's a loss of over $2,000 by gambling on the stock market instead of the NFL!

Note that I'm not advocating betting on the NFL or the stock market - if you did nothing with your money, you'd have $8,010 - more than either of the two options! Anyway, onto last week's review.

Results Summary

Green Bay is potentially without Aaron Rodgers, so that game is completely off the boards in all of Vegas - they won't put odds on it until they have at least some certainty on who's in or out. My guess is that Green Bay is the favorite either way, but the spread and the money line will be different depending on if he plays or not. Honestly, it's hard to imagine him playing with a separated shoulder, but I guess we'll see.

Check back next week for the results and more picks.

Tags: | |

Category: Football

Leave a comment


 

Traffic Stats and Google Chrome

posted on 10/02/08 at 12:36:38 am by Joel Ross

Now that Google's new browser, Chrome, has been released for a month, I figured I'd take a look at my blog's statistics to see how it's affected overall browser stats. Even though it's only been a month, a few things jump out as interesting to me.

First, in the past month, over 7.5% of my traffic is now using Chrome. That's a pretty good number considering they are just getting into the browser business. If you could pick a market, and gain a 7.5% share in less than a month, you'd be crazy not to! But where is the market share coming from? Well, for me, Firefox is down 4% and IE is down over 5%! I find it surprising that a lot of the gain comes at the expense of IE. I guess IE users are looking for alternatives, but it's surprising that they haven't gone to Firefox.

So IE and Firefox dropped a total of 9%, but Chrome is only at 7.5%. Where did the rest go? Opera! My Opera traffic is up 50% - yeah, the percentage is still small, but that's a pretty big increase for a browser that's been around for a long time. I guess having a new browser show up helps people renew their interest in other browsers.

After doing the analysis against my blog, I decided to take a look at the stats for a more mainstream site - or rather a set of sites. I took a look at the Develomatic suite of sites: Tourneytopia, MyPlayoffs.com, Tourney Logic, and Pay It Square. My guess was that my traffic is a bit different, since it's a more technical audience. During the time when Chrome was released, we were running a US Open tennis tournament for The Tennis Channel on Tourneytopia, so the traffic was pretty good there, and definitely a different audience than my blog. What did I see? Well, Chrome visitors comprised less than 0.5% of traffic! Also, IE is still king (whereas Firefox is now my blog's number one browser) and Safari gets about double the amount of usage as on my blog.

So while Google Chrome seems to be taking hold in the geek world, it definitely has not caught fire in the mainstream world. I guess they're just behind the curve!

Tags: | | |

Category: General

2 comments


 

NFL Picks: 08-09 Week 3 Results and Week 4 Picks

posted on 09/25/08 at 08:00:00 pm by Joel Ross

The long national nightmare is over! Ok, so it wasn't national. It was mainly centered in Michigan. Either way, Matt Millen has been fired! Now, the question is who will be the replacement? And how long will it take to undo what Millen did? Anyway, on to last week's results.

Results Summary

Overall, I'm not doing too bad with my picks. However, with the way payouts work, I'd still be down overall. You have to do seriously well with picks to make any money - something in the neighborhood of 70% correct with picks. I'm not quite there! Anyway, here's next weeks picks.

Check back next week for results, and a new set of picks.

Tags: | |

Category: Football

Leave a comment


 

Building Your Idea Through Angel Investing

posted on 09/23/08 at 08:00:00 pm by Joel Ross

At the last GR Tech Lunch, we had Bill Klevin as our guest speaker. Bill runs DaVinci Capital, a small company in Grand Rapids focused on helping entrepreneurs secure funding to build their business. He mainly deals with Angel investors, particularly the Grand Angels. Well, at least until October, when he's moving to Wyoming and DaVinci will be closing their doors.

We had a pretty good turn out, and Bill did a great job of capturing everyone's attention in the room - so much so that he didn't get an opportunity to even eat his lunch. We kept him there for the majority of the hour and a half, and he did a great job explaining the process you'd go through and answering everyone's questions.

He laid out three things that are key to have before you even consider getting angel funding:

Then he talked about the process to actually get in front of Angel investors, and what will happen after you get funding. There's a lot of up-front work to ensure that your business plan is solid, that you have good documentation of your company and it's predicted growth, and that you have a solid plan for how you will use the money. That process will take 6-8 weeks. Then you get in front of the investors for your presentation - where you get 15-20 minutes to pitch your idea. Then they'll either send you packing, or do further investigation.

Having gone through the process, I found one particular detail interesting that I didn't realize before: you wouldn't get funding from the group - it would be from just a handful of people that found your idea to be interesting. And in a lot of cases, you might end up getting funding from multiple angel investment groups. If you're looking for $1,500,000, you might get $50,000 from a few people, $100,000 from a few more, and it will slowly add up until you get the amount you need. That process usually takes another 6-8 weeks, so you're looking at about 3-4 months from the time you start to the time you have money. And once you have the money, you'll also put together a Board, where you'll update your investors on the current status, as well as have a sounding board to give you advice when you need it. The Board will usually consist of four or five people, so it probably won't include all of your investors. The good part of that is that you can lean on board members to give you advice and/or contacts when you need them.

Anyway, the lunch and information was great. I really enjoyed listening to Bill talk, and will be sad to see him leave the area. If you're in the Grand Rapids area, you should definitely come out for the next one! First Monday of every month.

Tags: |

Category: General

Leave a comment


 

So, What is Duck Typing?

posted on 09/21/08 at 09:19:28 pm by Joel Ross

I recently had a discussion with someone about duck typing, and my understanding of it was called into question. He's much smarter than I am, so I assumed he was right, but afterwards, I decided to do a little digging. I think I was right, but there's not a ton of information out there, so I'm going to lay out what I think Duck Typing is, and let you poke holes in it, and tell me where I'm wrong.

First, though, let's lay out the definition of Duck Typing. From the Wikipedia article:

duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class.

Or, as James Whitcomb Riley put it:

If it walks like a duck and quacks like a duck, I would call it a duck.

So what does that mean? From my understanding, it meant that as long as I pass something into a method and it supports the interface the method expects, than it'll work. For example, let's say I have the following method:

   1:  public void SendEmail(SmtpMailer mailer, string subject, string body)
   2:  {
   3:    mailer.SendMessage(subject, body);
   4:  }

This method relies on a concrete class - SmtpMailer. But what if I wanted to pass in a different class to this method? Well, the normal way to do this would be to create an interface, have SmtpMailer implement that interface, and change this method to work against an interface rather than a concrete implementation. But there's two potential downfalls of that approach. First, what if you don't have access to change the SmtpMailer class? You can't just add an interface to it, so the solution is the same, except you'd have to create an implementation of IMailer that adapts the SmtpMailer class to IMailer (a good design decision anyway). But what if this method isn't accessible for change? Then what? You could inherit from SmtpMailer and override the SendMail method, and pass in that class instead. And if both are inaccessible to you? Well, then you've got a lot of work to do to break this code apart.

All of that requires a lot of code to work around the issue. But with (my understanding of) duck typing, it's simple and requires no code changes to SendMail or the SmtpMailer class. All I have to do is have a class that satisfies the requirements of the SendEmail method. In other words, I can pass any class into this method, as long as it has a method called SendMessage that takes two strings as parameters. So, this would work:

   1:  public class InstantMessage
   2:  {
   3:    public void SendMessage(string subject, string body)
   4:    {
   5:      // Send subject and body via Instant Message
   6:    }
   7:  }

Now, my background is almost completely in statically typed languages, so to me, this is a pretty big paradigm shift. Maybe for those who are used to working in a dynamic language (like Ruby) on a regular basis, it's not that big of a deal. To me, it seems like a good way to deal with those tough-to-break dependencies.

Now, when I described the above as Duck Typing, I was told that wasn't actually what duck typing was. Here's how it was described to me. Essentially, a variable can change types based on the way it's assigned - like what JavaScript provides. You can declare a variable and use it like so:

   1:  var x = new Array();
   2:   
   3:  x[0] = "One";
   4:  x[1] = "two";
   5:  x[2] = "three";
   6:   
   7:  alert(x.length);

Calling length on x returns 3 - the length of the array. Because x is being used as an array, that's how the method responds. But since Javascript is dynamically typed, I can later repurpose x:

   1:  x = x.join("");
   2:  alert(x.length);

In this case, x (the same variable) acts like a string after the join call, so length will return 11 (the length of the joined string).

If the latter is actually duck typing, than there's no difference between duck typing and dynamic typing. But I don't think that's the case. What I've found seems to support what I'm saying, but I've also seen conflicting definitions. So I'm turning to people smarter than me to tell me what duck typing really is - you!

Tags: | |

Category: Development

24 comments


 

NFL Picks: 08-09 Week 2 Results and Week 3 Picks

posted on 09/18/08 at 08:00:00 pm by Joel Ross

During the pre-season, I wondered if the Packers were making the right decision about Favre. Yeah, long term, they knew it was time to move on, but short term, would they be better off with Favre this year, given that Aaron Rodgers has never started an NFL game? Well, if the first two games are any indication, Green Bay should be fine - both short term and long term!

Anyway, onto results. There's a new color this week - blue means the game was a push for the spread. And a game is missing, since the Ravens / Texans game was rescheduled for November.

Results Summary

As usual, I'm doing decent at picking games, while doing poorly against the spread and over / under. Oh well. Anyway, onto next week's games.

Check back next week for the results and new picks.

Tags: | |

Category: Football

Leave a comment


 

CauseCast

posted on 09/11/08 at 08:00:00 pm by Joel Ross

The other night, I got an email from my cousin. We don't communicate as much as we probably should (my fault), but she will periodically send out emails talking about milestones in her life. That evening, it was about her latest project that launched that day: CauseCast.

What caught my interest was the fact that it's launch was planned around their presentation at the TechCrunch50. TechCrunch50 is a Silicon Valley conference aimed at looking at start-ups and helping them launch. While CauseCast didn't win, it's still a pretty cool honor to even be selected to present at the conference.

I honestly don't know much about CauseCast, as I hadn't even heard of it until I got the email. But it does sound like a cool idea - their idea is to highlight 10 non-profit companies a month, pairing them up with a figure of some sort to help with their cause. And since this is a Web 2.0 world, there's a social networking side thrown in as well.

Anyway, it's always cool to see what others are working on - especially when it's someone in your family. Shortly after this whole thing came about, I found out my cousin is also on Twitter, and since I'm a huge Twitter fan, maybe I'll actually be able to stay in touch now!

Tags: |

Category: Software

Leave a comment


 

NFL Picks: 08-09 Week 1 Results and Week 2 Picks

posted on 09/10/08 at 10:23:00 pm by Joel Ross

What a first week! Every year, it seems like at least one major player goes down and is either out for an extended period before returning, or is done for the year. This year, obviously, is no different. And the effects are eye opening. With Tom Brady done for the year, the Patriots go from a team who was routinely favored by 10+ points last year, to a team who's the underdog in week two - to the Jets no less!

Anyway, this year, rather than doing a results post and a picks post, I'm going to combine them into one. I'll start with my picks for the next week, and follow it up with results. So, with that, here's my picks for the week.

Results had been a little complicated in the past, so I decided to simplify what I post a bit. Green indicates a correct pick. Red is wrong. My original pick is bold and * still indicates a cover of the spread, but an ultimate loss. At the bottom is a summary of how I did. I'm still tracking everything I tracked before, so I know how much money I would have won or lost if I actually bet, but there's not a whole lot of need to post that, I don't think.

Results Summary

Check back next week for the results and another round of picks.

Tags: | |

Category: Football

Leave a comment


 

Moving into the Cloud

posted on 09/09/08 at 01:17:54 am by Joel Ross

I often wonder how much I rely on my laptop. And I'm not referring to development, but for the other things I do - email, twitter, IM, IRC, and RSS feeds. Or put another way, how much of a performance hit am I taking by running those things locally? My laptop has 3.325 GB of RAM (don't ask! I'm still bitter). After a normal day of usage, here's the memory usage of some of my "utility" applications:

That's a total of 731 MB. In fairness, that includes paged memory, but still, that's a fair amount of memory. I did have to reboot today - I know Outlook and FeedDemon can get much higher than that when they've been running for a few days. So I started to see if I could move my utilities online - run them in a browser rather than a stand-alone client. There's no point in talking about twitter or the other social networking sites - those are pretty obvious, since they started online and it's only out of convenience that you move them offline. But even for the rest, it's not that hard to do, if you know the right tools.

Email

Email is probably the easiest one to move online - people have been doing online email forever. Email is inherently online. There are lots of options - for personal email, at least. I use Google Apps For Your Domain, and have been very happy with that decision since I switched. The more and more I use the Gmail interface, the more I like it - the keyboard shortcuts are intuitive and despite it being a web application, it actually responds quicker than Outlook sometimes. There are plenty of other online email systems out there - Yahoo and Live Mail are the two other large players I can think of right now, but pretty much every ISP and web host will provide some sort of online interface.

The challenging accounts to get online are the corporate ones. Luckily for me, RCM (and NuSoft before them) offers Outlook Web Access, so that was an easy one. For companies that don't offer an online interface, I'm not sure how you could handle it - I would NOT recommend blindly forwarding all email through another online account, such as Gmail, though.

IM / IRC

I've used Trillian since the days of the "IM Wars" - back when AIM would update their protocols on an almost daily basis, and Trillian would hurry to push out an update shortly afterwards. That was back in 2001, I think. I use it for instant messaging on MSN, AIM, Yahoo, Jabber (well, GTalk, actually), and RCM's LCS server.

Again, the easy part of moving these online are the large, public services. Meebo can handle ICQ, MSN, AIM, Yahoo,  Jabber and GTalk, so I'm set there. Meebo's interface is actually pretty good, and you can create an overall account that allows you to store preferences about your IM experience, as well as your different IM accounts. There's even a firefox add-in to show toast whenever you get an IM.

I also use Trillian to connect to IRC channels, and luckily, there's a solid web replacement for that as well. I first heard about Mibbit as a way to get around corporate firewalls that block the ports needed by IRC, but it's also a solid IRC client, even when you have the option of a desktop client. It's a lot like Meebo, in that you can create an account and store the different servers / rooms you access so you don't have to enter them every time.

About the only thing I think I'd miss by moving IM / IRC online is the logs - Trillian logs everything for me, so I can go back later and review. I'm not sure I could get that if I'm using an online system. That would prevent having discussions like this available for future reference.

RSS Feeds

I have never really liked the options for reading feeds online. I started with RSS feeds in RSS Bandit, moved to Newsgator Inbox, and eventually settled on FeedDemon. But I know I'm probably in the minority. Just based off of my FeedBurner stats more than 50% of my subscribers are reading this in a web browser - possibly even 75%. Google Reader and Bloglines are the two most popular options, but Newsgator also offers a decent online offering as well - and it integrates read status with FeedDemon.

So Now What?

I went through this exercise, and ultimately only stuck with one of the options - I have removed my personal email from Outlook, and solely use the Gmail interface. Other than that, I've settled back into my old ways. But I at least know I have the option, and if I had to, I could move online in a heartbeat - the online stuff is all set up. It's just a matter of pulling the trigger and moving to it. It's also nice to be able to sit down at a different computer and know that I have the ability to get at the information I want to be able to get at. But at least for now, I'll stick to the thick clients.

Category: General, Software

Leave a comment


 

NFL Picks: 08-09 Week 1

posted on 09/04/08 at 06:00:00 pm by Joel Ross

For those new to the blog since January, come Fall, I change gears a bit. One of the things I've done every year since I started this blog is post my weekly picks. Then, after the games are played, I post the results, and the whole cycle starts over. I'm not sure how many people actually read my picks or care who I pick, but I'm going to continue the tradition. This year though, I think I'll trim it back a bit, and make it only one post per week, rather than the usual two.

I'm in two fantasy leagues this year, which should give me something interesting to follow for just about every game. For the record, the team I pick is in bold. If there's a * next to the team, that means I picked them to cover the spread, but ultimately lose. The over/under pick is also in bold.

Anyway, on to the picks for the first week of the 2008-2009 NFL season.

I'm very excited for this season to get going! I can't wait for Thursday night. Anyway, check back next week to see how I did - I'll post a summary, along with the picks for the following week.

Tags: | |

Category: Football

Leave a comment


 

Getting Rid Of Config Files with Fluent NHibernate

posted on 09/03/08 at 07:00:00 pm by Joel Ross

When I first looked at NHibernate, the biggest issue I had with it was the configuration files - they looked long, confusing and error-prone. Well, as evidenced by a previous post, I got over that, and did it anyway.

But just because I figured it out doesn't mean I was happy with it, or that it's still not error prone. Luckily, there's a solution: Fluent NHibernate. I'm not sure why it's called that, other than it has a fluent interface, but it's goal is to allow you to programmatically specify NHibernate configurations.

From my previous post, here was my config for my Team class:

   1:  <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="CP.Models" namespace="CP.Models">
   2:    <class name="CP.Models.Team" table="Teams">
   3:      <id name="TeamId" column="TeamId" type="Int32" unsaved-value="0">
   4:        <generator class="native" />
   5:      </id>
   6:      <property name="Abbreviation" column="Abbreviation" type="string" length="50" not-null="false" />
   7:      <property name="Location" column="Location" type="string" length="50" not-null="false" />
   8:      <property name="NickName" column="NickName" type="string" length="50" not-null="false" />
   9:    </class>
  10:  </hibernate-mapping>

This is embedded in my DLLs, and it's just text. Hitting F5 doesn't do anything to verify this is correct. That's the problem Fluent NHibernate looks to solve. So I added the references to my Models class, and created a few mapping classes. Here's what the TeamMap class looks like:

   1:  public class TeamMap : ClassMap<Team>
   2:  {
   3:    public TeamMap()
   4:    {
   5:      TableName = "cpTeams";
   6:      Id(x => x.TeamId).GeneratedBy.Native();
   7:      Map(x => x.Abbreviation);
   8:      Map(x => x.Location);
   9:      Map(x => x.NickName);
  10:    }
  11:  }

This is much, much better, because now any change in our model (renaming properties, etc.) or a misspelling in our mapping is caught by the compiler. Not only that, but if we're smart about how we make our changes and use a refactoring tool, the mapping gets updated automatically for us. Also, it lets us specify things in one place instead of two. I don't have to spell out the types of each property - it's looking at the entity, so it knows the type already.

But the question still remained for me - can I do the complicated stuff for mapping properties. The answer is yes. Here's the class to map my Game class, which has a few relationships (explained in the previous post):

   1:  public class GameMap : ClassMap<Game>
   2:  {
   3:    public GameMap()
   4:    {
   5:      TableName = "cpGames";
   6:      Id(x => x.GameId).GeneratedBy.Native();
   7:      References(x => x.Week).WithForeignKey("WeekId").Cascade.All().FetchType.Join();
   8:      References(x => x.HomeTeam).WithForeignKey("HomeTeamId").Cascade.All().FetchType.Join();
   9:      References(x => x.AwayTeam).WithForeignKey("AwayTeamId").Cascade.All().FetchType.Join();
  10:      References(x => x.Season).WithForeignKey("SeasonId").Cascade.All().FetchType.Join();
  11:    }
  12:  }

Now, here is where I had an issue. The "WithForeignKey" method doesn't seem to work. It looked for the property name + "_id" to be the field name in the database, and I don't use underscores in my columns. That call should have overridden the conventions used, but it didn't.

After a quick call for help on twitter, I found my answer in the source for Fluent NHibernate. There are conventions that handle how properties and references are mapped to columns when you don't explicitly state them. Turns out it's fairly easy to change those conventions, and you don't even have to change the source of Fluent NHibernate, which is nice. I'll show that, but it's part of the overall configuration for NHibernate. This is in my NHibernateHelper class from the other post:

   1:  public class NHibernateHelper
   2:  {
   3:    private static ISessionFactory _sessionFactory;
   4:    private static ISessionFactory SessionFactory
   5:    {
   6:      get
   7:      {
   8:        if (_sessionFactory == null)
   9:        {
  10:          var configuration = MsSqlConfiguration
  11:            .MsSql2005
  12:            .ConnectionString.Is("server=(local);Initial Catalog=CP;User Id=sa;Password=;")
  13:            .ShowSql()
  14:            .ConfigureProperties(new Configuration());
  15:        
  16:          var persistenceModel = new PersistenceModel();
  17:   
  18:          persistenceModel.Conventions.GetForeignKeyName = (prop => prop.Name + "Id");
  19:          persistenceModel.Conventions.GetForeignKeyNameOfParent = (prop => prop.Name + "Id");
  20:          persistenceModel.addMappingsFromAssembly(
  21:         Assembly.Load(Assembly.GetExecutingAssembly().FullName));
  22:          persistenceModel.Configure(configuration);
  23:   
  24:          _sessionFactory = configuration.BuildSessionFactory();
  25:        }
  26:        return _sessionFactory;
  27:      }
  28:    }
  29:   
  30:    public static ISession OpenSession()
  31:    {
  32:      return SessionFactory.OpenSession();
  33:    }
  34:  }

This is a big change from my last sample. Part of the reason for that is that I've also eliminated the need to have a hibernate.cfg.xml file - it's all part of the above code. Most of the hibernate.cfg.xml elimination code was borrowed from a post on the NHibernate FAQ blog, but one thing that caught me up a bit was that you don't actually call configuration.Configure() any more, since that looks for the hibernate.cfg.xml file, and will throw an error. Now you call ConfigureProperties() passing in a configuration (line 14). Lines 18 and 19 is where I change the conventions used by Fluent NHibernate from looking for HomeTeam_id to HomeTeamId. The rest is pretty similar to the previous example.

After doing this, I was able to eliminate all of my NHibernate-specific XML files, and everything worked as it did before. All in all, it took about an hour to switch it all over. Not bad, considering what I'm gaining in maintainability down the line.

Category: Development, Software, C#

6 comments


 

Grand Rapids Tech Lunch – Monday, September 8th

posted on 09/02/08 at 04:30:06 pm by Joel Ross

The fourth Grand Rapids TechLunch is coming up quickly, and I'm excited about our guest this time around. We're going to have Bill Kleven, who is a partner at DaVinci Capital, a local firm who's goal is to help businesses develop business strategies and secure financing to fund their business. He's going to be talking about the process that you'd go through to bring your idea to fruition.

It should be a good discussion, so head over to the GRTechLunch site and RSVP!

Category: General

Leave a comment


 

Entities and Repositories Discussion

posted on 08/28/08 at 06:13:35 pm by Joel Ross

Earlier today, there was a great discussion in an IRC channel about entities and whether they should have behaviors or not, and that eventually moved onto Repositories. It's a good discussion and after it was over, several of us felt it would be a good reference for later. Since I have a log of the conversation, I figured I'd repost it for future reference. Hopefully, you'll find it a good read as well.

For a bit of reference, this conversation took place in ##twittertribe on irc.freenode.net (yes, a double #). The main players are (in order of appearance) Michael Eaton (mjeaton), Eric Ridgeway (Ang3lFir3), Nate Kohari (nkohari), Matt Davis (mattsonlyattack), James Avery (averyj), Michael Letterle (TheProkrammer), me (RossCode), James Bender (JamesBender), Jay Wren (evarlast), and Nick Quaranto (qrush).

mjeaton: Ok.  Entities - behaviors: yes or no?
Ang3lFir3: mjeaton: yes?
mjeaton: Ang3lFir3: serious question.  what do you think?
nkohari: mjeaton: if you mean behaviors as in business logic, yes
Ang3lFir3: mjeaton: i've heard yes.. and I think its reasonable.... but i also think it could get out of hand
mjeaton: Ok.  Customer class.  Does it have a .Save()?
mattsonlyattack: activerecord--
Ang3lFir3: i see visions of Entities with 10 properties and 15 "Actions"
averyj: mjeaton: I would say yes
TheProkrammer: mjeaton: Ideally, no.
mjeaton: I LOVE IRC!
TheProkrammer: awesome. :)
Ang3lFir3: mjeaton: it has a Save if you are using active record
averyj: but if you want to be all IOC you could have the Customer class take an ICustomerRepository
mjeaton: you guys rock.  guaranteed that any question I ask will result in a 50/50 split
averyj: and it uses that to save
TheProkrammer: Customers.Save(customer)
RossCode: mjeaton: I can see both ways, but for the most part, yes
nkohari: averyj: false
averyj: lol
nkohari: you want the ICustomerRepository to take a Customer, not the other way around
mattsonlyattack: the Customer class wouldn't take a repository
averyj: false
averyj: lol
mattsonlyattack: SRP bitches
nkohari: that's too activerecordy
JamesBender: Didn't we have this discussion already?
averyj: dont build an aenemic domain model for PIs sake
mjeaton: how many of you think PI is important?
nkohari: it's a nice-to-have
nkohari: it helps during development
RossCode: mjeaton: I don't, really
nkohari: but i don't buy the "oh i might switch dbms's" argument
mjeaton: nkohari: how does it help?
Ang3lFir3: PI is pretty.... but i would decide based on project scale
JamesBender: It makes some things easier
evarlast: averyj: the customer class wouldn't take an ICustomerRepository.
evarlast: Customer should have no deps other than its object relations.
nkohari: mjeaton: you can design against your domain model without worrying about where the entities are stored
nkohari: and you can create an in-memory backing store for testing
Ang3lFir3: scale and complexity of the domain... simple domain then i prolly don't need PI ... and go straight to AR
mjeaton: nkohari: /devils_advocate: explain domain model
nkohari: so you don't need to have a database during testing
evarlast: Repositories know about entities, but Entities need not and shouldn't know about their repositories.  NH FTW, Entity Framework FTL
Ang3lFir3: evarlast++
nkohari: the term "domain model" sucks, but to me it means the entities that represent your business... ie. customer, order, invoice
RossCode: even with activerecord, you don't necessarily have to have a database to test
Ang3lFir3: nkohari: true
mjeaton: Ok.  So UI talks to controller.  Controller talks to ??
nkohari: repository
mjeaton: UI=View
nkohari: ICustomerRepository, for example
Ang3lFir3: mjeaton: controller uses repo and sends data to View (UI)
mjeaton: Controller talks to repository and returns instances/collections of Entities?
nkohari: yes
mattsonlyattack: or an application service
RossCode: nkohari: do you have one repository or multiple repositories?
mjeaton: mattsonlyattack: explain.
Ang3lFir3: technically the returned instances don't HAVE to be entities
nkohari: RossCode: lately i've been using one
evarlast: the nice thing about repo model is when you scale you can scale out and instead of talking direct to DB you can make your Repo talk to a web service or maybe something simple like ASP Dynamic Data and your entities and repository interfaces dont' change.
nkohari: but you can only get away with that in some cases
RossCode: nkohari: how do you handle custom queries? Pass in ICriteria?
Ang3lFir3: isn't the multiple repo thing about when you get into Aggregate roots etc?
mattsonlyattack: for behaviors that don't directly map to a single entity some times services are used to control the collaboration, and they'll use respositories as well
nkohari: yeah, in the past i have, but lately i've moved to linq for nh
nkohari: so it's all Expression<Func<T, bool>>s
Ang3lFir3: linq for nh FTW
RossCode: nkohari: but then aren't your queries and how you query data in your controllers now?
nkohari: "expressionfunktybools"
nkohari: RossCode: touche ;)
nkohari: chadmyers was just talking about that
nkohari: he suggests creating query objects
nkohari: which is actually a very good idea
evarlast: if you look at the whole NH Criteria API, its mostly duplicate of what is now available with Expression<> in 3.5
nkohari: evarlast: that's the idea
mjeaton: someone raise d a good question: one repository or multiple?
nkohari: it's a linq provider...
RossCode: nkohari: I'm not saying it's bad. I think I would rather encapsulate how I get my data in a repository and have hte controller call the repository
nkohari: RossCode: you can definitely do that
nkohari: the other argument is that you have one 'data context' that provides low-level access to the IQueryable<T>s
nkohari: and then you build repositories on top of that
mattsonlyattack: one repository per aggregate root is the standard response
nkohari: bradwilson was advocating that on twitter
mjeaton: mattsonlyattack: don't want standard response.  i want to know what you guys are doing.
nkohari: mattsonlyattack: yeah, there's more flexibility there for sure
Ang3lFir3: mattsonlyattack: define aggregate root.... cuz no one has done that very well yet
RossCode: nkohari: that makes sense - so public repositories all talk to one lower level repository?
RossCode: Ang3lFir3: have you watched the DDD chalk talk by bsimser?
nkohari: RossCode: yeah, the data context is just an object with a bunch of IQueryable<T> properties
mattsonlyattack: watching that greg young chalk talk is good for this question
Ang3lFir3: RossCode: yup... he didn't make it clear enough
nkohari: and then you can create a mock one by implementing each with a List<T> (i think?)
mattsonlyattack: it seems he redrew boundries for multiple aggregate roots with the same sets of entities
mjeaton: see, when i hear nkohari go off like that, I think "wow, complexity.  is it needed?"
nkohari: mjeaton: nope, it's not
mjeaton: of course, I'm the dumbest guy in this channel right now...
Ang3lFir3: mattsonlyattack: that is supposed to be ok... some aggregate roots are allowed to have the same entities in them... they are supposed to be about concepts i think
JamesBender: mjeaton No you're not.
mattsonlyattack: mjeaton: not the dumbest by a long shot
averyj: If I was building bank sofware, I would do all of this
nkohari: it's not important in all cases
RossCode: mjeaton: depends on how big the project is, I would say
averyj: but I am not, I am building simple software
averyj: so I just need simple solutions
Ang3lFir3: mjeaton:  no you aren't
nkohari: if you code against repositories though you get some benefits
mjeaton: averyj++
nkohari: like for example
averyj: ActiveRecord is simple
mattsonlyattack: Ang3lFir3: agreed, the aggregates help w/logical paths to other objects
nkohari: ideavine reads info from xml files right now
nkohari: but eventually we might want to move it to a db
averyj: YAGNI
nkohari: that's ultra-simple with a repository-based approach
averyj: use tests and re-factor
nkohari: i'm not disagreeing with that
averyj: we might never move it though, and now we have un-needed complexity
nkohari: but this approach lets you refactor less
nkohari: not really
mjeaton: all of you need to go to summer camp dammit.
nkohari: what else would i have done?
averyj: I agree we need to design for change, but isn't that what my unit tests are?
mattsonlyattack: mjeaton++
nkohari: private methods that would read the xml?
nkohari: that's not any easier than what i did
averyj: yeah, I can see that
mattsonlyattack: http://weblogs.asp.net/bsimser/archive/2008/08/16/alt-net-canada-day-2-ddd-and-more-d.aspx
Ang3lFir3: my issue in our domain is that while I have entities of the same types...the definition of those entities is different for all implementations
averyj: the repository for getting the XML makes sense because you had to have something to do that
nkohari: i guarantee, once you grok DI this stuff doesn't sound nearly as complex
averyj: and that is a good simple pattern
JamesBender: nkohari++
averyj: Its not the complexity that bothers me as much as the obfuscation of the code
nkohari: i just naturally smash this stuff out now
nkohari: averyj: that's true
nkohari: that's why i favor [Inject] actually
averyj: It is way harder for me to grok an application like that, especially when there are levels and levels of stuff being injected
RossCode: averyj; I agree- that's one of the problems I have with interfaces for everything

After a short lull (not fit to be reprinted here), James Avery got the conversation back on track.

averyj: ok, repository question for the room. I actually did a 2 year project using the pattern we are talking about but we used a generic Repository, what the reason to have a separate CustomerRepository?
nkohari: averyj: you can wrap queries inside the repository
nkohari: er, customerrepository
mjeaton: so, IRepository<T> vs. IFooRepository?
nkohari: queries with business logic in them, like GetAllLoyalCustomers()
averyj: we actually had just one Repository and it had stuff like Save<>
averyj: its the one Dave made open source
averyj: NHibernateRepository I think
nkohari: yeah
mjeaton: averyj: yea, we used that on a project.
evarlast: Save<> ?  that is horrible
averyj: actually based on Bellwares code from like 4 years ago
RossCode: averyj: where do you put code for things like GetCustomersByFirstName?
averyj: on this project we had separate data objects when we needed them
TheProkrammer: Customers.Find( c => c.FirstName = "value")
TheProkrammer: err ==
averyj: but I could see that, use CustomerRepository for the custom queries
RossCode: TheProkrammer: in your controllers?
averyj: so yo have a base repostiory it all inherits form?
TheProkrammer: bah, I'm working here, stop making me think.
RossCode: averyj: I laid out what I did in a blog post just last night
RossCode: I used an interface and extension methods
mjeaton: RossCode: link?
RossCode: http://www.rosscode.com/blog/index.php?title=playing_with_nhibernate&more=1&c=1&tb=1&pb=1
RossCode: Note: I've been playing with NHibernate for 1 week, so i could be completely off base. I probably am
averyj: intereting, why not use a base class?
RossCode: testing, mainly. Since it's interface based, I can use Moq to mock the repositories
averyj: you can still have an interface
averyj: just thinking instead of the extension methods you could haev a base class
qrush: Moq?
averyj: I could be missing something though
RossCode: so have CustomerRepository: IRepository<T>, BaseRepository?
mattsonlyattack: qrush: http://code.google.com/p/moq/
RossCode: I think I tried that, but then BaseRepository has no knowldege of T
mjeaton: Moq is cool, but people tell me Rhino caught up with the features.
RossCode: I guess I could have made it BaseRepository<T>
qrush: but seriously. lots of new libs using 3.5
qrush: i need to try it someday :/
RossCode: mjeaton: I saw the new syntax for Rhino recently - very similar to Moq's syntax
RossCode: I picked Moq before I saw the new way Rhino works. The old way looked too complicated for me
mjeaton: wishes he was sitting with rosscode, averyj and a laptop right now.
mjeaton: RossCode, agreed.  The record/playback stuff was crap.
mattsonlyattack: which was still in moq, just implied by the syntax
mjeaton: right.
mattsonlyattack: moq is still sexy
RossCode: You guys are ruining my day. I'm supposed to be working. How am I supposed to prepare for the fantasy draft tonight?

This is the power of the tribe - impromptu discussions on just about any topic. It's guaranteed to generate a conversation. Want to be part of the next one? Stop by - we'll be there!

kick it on DotNetKicks.com

Category: Development

14 comments


 

Playing With NHibernate

posted on 08/27/08 at 11:52:42 pm by Joel Ross

Over the past week or so, I've been dabbling with NHibernate. As may be apparent from reading my latest posts over the past few weeks, I've been digging into automated testing more and more, and as I've looked at how I can make the Kinetic Framework more testable, I decided to look elsewhere to see how others are doing it.

NHibernate is probably the most popular ORM tool in the .NET space right now, so it was the obvious place to turn. It's been around for a long time, and it's a tool that's been on my list to learn for a while.

As it turns out, it's actually not that bad to get working. To be honest, I was intimidated by the XML configuration files, but I dove in and eventually figured it out. I started with a very simple object model - the beginnings of a side project I've been thinking about starting. It has four tables - Games, Teams, Weeks, and Seasons. The intent of these tables is to be able to build a schedule for the NFL. You'll see the data I'm storing as we explore the objects further, but I do have a few relatively complicated relationships here. Seasons have a collection of games (by week), and Games are made up of a Season, a Week, a Home Team and an Away Team.

The models themselves are pretty much POCOs. For example, here's my Team class:

   1:  public class Team
   2:  {
   3:    public virtual int TeamId { get; set; }
   4:    public virtual string Abbreviation { get; set; }
   5:    public virtual string Location { get; set; }
   6:    public virtual string NickName { get; set; }
   7:  }

Like I said - there isn't much there. The virtual keyword is required by NHibernate (as is a default constructor - I didn't include it, but it's implied).

The part I was most worried about was the mapping files. In reality, the mapping file is more complicated than the object itself, but it's not that bad. Here's the Team object mapping XML:

   1:  <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="CP.Models" namespace="CP.Models">
   2:    <class name="CP.Models.Team" table="Teams">
   3:      <id name="TeamId" column="TeamId" type="Int32" unsaved-value="0">
   4:        <generator class="native" />
   5:      </id>
   6:      <property name="Abbreviation" column="Abbreviation" type="string" length="50" not-null="false"/>
   7:      <property name="Location" column="Location" type="string" length="50" not-null="false" />
   8:      <property name="NickName" column="NickName" type="string" length="50" not-null="false" />
   9:    </class>
  10:  </hibernate-mapping>

There's a few interesting things here. First, the Id element. This defines how a Team can be identified from other teams. In my database, it's an auto-number int, and I want to allow my database to manage the numbering. First, I map my identifying property to TeamId, which maps to TeamId in the database. The generator specifies how NHibernate should figure out what a new Id should be. "Native" tells NHibernate to pick the best method for getting the id. In this case, it'll let the database handle it. The other property elements are pretty straightforward - just how each property on my Team class is mapped to the database, it's type, whether it can be null, and it's length.

The interesting (and intimidating) part of the mapping files is more evident when we look at the Game class.

   1:  public class Game
   2:  {
   3:    public virtual int GameId { get; set; }
   4:    public virtual Week Week { get; set; }
   5:    public virtual Season Season { get; set; }
   6:    public virtual Team HomeTeam { get; set; }
   7:    public virtual Team AwayTeam { get; set; }
   8:  }

The game class shows it's relationships. How those manifest themselves is evident through its mapping file, which is a bit more complicated.

   1:  <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="CP.Models" namespace="CP.Models">
   2:    <class name="CP.Models.Game" table="Games">
   3:      <id name="GameId" column="GameId" type="Int32" unsaved-value="0">
   4:        <generator class="native" />
   5:      </id>
   6:      <many-to-one name="Week" column="WeekId" not-null="true" 
   7:        fetch="join" outer-join="false" cascade="save-update" />
   8:      <many-to-one name="HomeTeam" column="HomeTeamId" not-null="true" 
   9:        cascade="save-update" fetch="join" outer-join="false"  />
  10:      <many-to-one name="AwayTeam" column="AwayTeamId" not-null="true" 
  11:        cascade="save-update" fetch="join" outer-join="false" />
  12:      <many-to-one name="Season" column="SeasonId" not-null="true" 
  13:        cascade="save-update" fetch="join" outer-join="false" />
  14:    </class>
  15:  </hibernate-mapping>

The Id element is the same as above. The difference is that instead of properties, this object has other objects as part of it - the many-to-one elements. Each element maps to a property on the Game class, and specifies which column in the Games table to get the Id for the related object. The rest specify how it should get the data (I think - I got this working, and didn't look at it too much further yet).

Once I created all of the classes and created the mapping files (and the hibernate config file, which I won't show), it's just a matter of starting up the NHibernate configuration. At some point, I saw the idea of a helper class that you can use to get new NHibernate sessions, so that's what I went with.

   1:  public class NHibernateHelper
   2:  {
   3:    private static ISessionFactory _sessionFactory;
   4:    private static ISessionFactory SessionFactory
   5:    {
   6:      get
   7:      {
   8:        if (_sessionFactory == null)
   9:        {
  10:          var configuration = new Configuration().Configure();
  11:          configuration.AddAssembly(Assembly.GetExecutingAssembly());
  12:          _sessionFactory = configuration.BuildSessionFactory();
  13:        }
  14:        return _sessionFactory;
  15:      }
  16:    }
  17:   
  18:    public static ISession OpenSession()
  19:    {
  20:      return SessionFactory.OpenSession();
  21:    }
  22:  }

The first time this code gets called, it sets up NHibernate, and tells it to look for configurations in the executing assembly (which contains both the mapping files as embedded resources and the models themselves). Once done, I can just call NHibernateHelper.OpenSession() and get a new session for working with my objects.

Once that was done, I started building repositories to talk to NHibernate to do the retrieval. I'm new to the Repository pattern, but based on a bit of research and a few samples, I came up with a base interface:

   1:  public interface IRepository<T> where T : new()
   2:  {
   3:    T Create();
   4:    T GetById(int id);
   5:    void Save(T model);
   6:    void Delete(T model);
   7:    ICollection<T> GetList();
   8:  }

I think, as I build this out more, I'll add more methods (or at least overloads to existing ones) that allow me to run queries, but for each object, I'll have a concrete implementation of the IRepository<T> interface for it. But the implementation for a lot of these methods will look very similar and have to deal with the details of sessions in NHibernate. For each of my repositories, I didn't want them to have to inherit from a base class that implements the interface, so I came up with a set of extension methods that handle the interface methods. Here's an example of the Delete() extension method:

   1:  internal static void Delete<T>(this IRepository<T> repository, T model) where T : new()
   2:  {
   3:    using (ISession session = NHibernateHelper.OpenSession())
   4:    {
   5:      using (ITransaction transaction = session.BeginTransaction())
   6:      {
   7:        session.Delete(model);
   8:        transaction.Commit();
   9:      }
  10:    }
  11:  }

This doesn't actually satisfy the interface requirements (I'm not sure an extension method even can do that), so in my repositories, I still have to make a call. Here's the call for delete in the TeamRepository (which implements IRepository<Team>):

   1:  public void Delete(Team team)
   2:  {
   3:    this.Delete<Team>(team);
   4:  }

Now, I can create new repositories quickly, and my physical implementation doesn't have to worry about the NHibernate details. Interestingly (and only in theory, since I haven't tried it), I could switch out extension methods, and switch which ORM tools I am using, since the only references to NHibernate is in the extension methods and the NHibernateHelper class (which, in turn, is only used by the extension methods).

Once this is all done, retrieving data is pretty simple. My sample application is written using the ASP.NET MVC framework, and my TeamController has a List method that's just this simple:

   1:  public ActionResult List()
   2:  {
   3:    return View(Repository.GetList());
   4:  }

That's it! I can get the data I need, without ever writing any data access code.

It's tough to compare this to the Kinetic Framework, as I still have some learning to do. The sheer amount of code I have to deal with is considerably less with NHibernate, but the majority of the code in the Kinetic Framework is generated, and not really something I have to maintain. This method does lend itself to being able to write automated tests for it, since I can mock the repositories easily, which is not easily accomplished in the Kinetic Framework (although a Repository pattern can be placed on top of the Kinetic Framework to do this).

I'll post more about my experimentations, but so far, I like NHibernate a lot. I'm still learning the ropes, and would like to know how the query is working - for example, when I get a game, does it retrieve the home team, away team, week, and season all in one query, or does it lazy load the properties as needed? I'll find that out, but I just haven't had the time yet.

Regardless, it's nice to use a solid framework and not have to worry about the ugly details underneath (or at least not have to be the one to maintain the ugly details!)

Category: Development, Software, C#

2 comments


 

How Many Levels of Abstraction Do You Care About?

posted on 08/24/08 at 11:16:01 pm by Joel Ross

There's been a lot of discussion on twitter recently about Drag-N-Drop (DND) software development, and whether or not that's good for the industry as a whole. Personally, I think it clouds the whole process by making it appear too simple, when in reality, we all know it's not that easy.

But it did get me thinking. DND and designer-based software development in general is really just about abstracting away the need to understand the code that is needed to place an element on a page away from the developer. And that's not necessarily a bad thing by itself. Abstracting away details is what makes software development easier. As a .NET programmer, I have yet to run into a situation where I truly cared about the IL my code generated. I've looked because I was curious, but at the end of the day, I didn't really care. And I definitely don't care how that IL becomes machine language, or how the OS handles that machine code.

Why don't I care about those abstractions, but I do care about the abstraction that DND coding provides? Because the abstractions I just mentioned aren't leaky. The DND example? It leaks. It leaks bad. And that's the main problem with DND - it's not inherently bad, it's that you have to have intimate knowledge of what is going on beneath the covers. The DND tools aren't to a point where they can completely abstract away the details from you, so what ends up happening is you spend more time in the details trying to figure out what the DND tool did (and why!) then it would take to just re-write the whole thing.

And that's when things get tricky. It's not the initial development - that part appears to work well. It's when you have to maintain the code because a requirement changes or a bug is found. Dropping a grid and binding directly to the database is simple initially, but what happens when you need to add a new field, and that's not easily bound to a database column? Things start to get a bit hairy, and you're left digging through lines and lines of generated code ("This code generated by a tool" is one of my favorite comments, by the way) to try to figure out what is going on. Or worse, you have to figure out if you can even do what's being asked of you with the current implementation. You might just have to start over!

And that's what makes DND development dangerous. It's dangerous in two ways. First, when it's demoed, it's viewed as being The Right Way to develop software, and while some of us realize that software development can't be done through a series of drag and drop components, some don't. We call them "Managers" and they wonder why a software project will take six months when you can just drag stuff around and make it work. Second, when you listen to your manager and you start to create software thinking that DND is the way to develop, you're left with unmaintainable code. Yeah, you impressed your manager with how fast you put together the new website, but now he has a few changes that he expects to be made just as quickly. Suddenly you realize how hard the current situation is to maintain, and you're left in the same spot - why are your changes taking longer than the initial development?

Some day, I would expect that DND tools will be sufficiently advanced that you can rely on them for both initial development as well as maintenance. The need to dig into the generated code will be eliminated, and the feature set available through DND will be on the same level as what's available today when you write code by hand. But that's not the case yet, which is why I cringe when I see people creating production level applications by dragging and dropping components and wiring up applications through a designer.

I know someday, I'll have to maintain it, and I can only hope that the tools have advanced far enough that I can do that easily.

Category: Development, C#

2 comments


 

Opportunistic Advertising?

posted on 08/15/08 at 12:44:14 am by Joel Ross

I spend most of my day in an IRC chat room (##twittertribe on irc.freenode.net - stop by and say hi sometime!), just kind of lurking to see if anything interesting comes along. Every now and then, I'll find a link worth clicking on. Today was one of those days, and I'm not sure why it caught my attention. It was an article about a Netflix outage, and I'm not even a Netflix subscriber!

Anyway, I was amused when I got there and saw this:

NetFlixOutage

Talk about opportunistic ad placement!

Category: General


 

Querying in the Kinetic Framework

posted on 08/14/08 at 08:00:00 pm by Joel Ross

I was chatting with a few people in IRC the other day about different development approaches, and I brought up the Kinetic Framework. Someone took a look at source of the samples and didn't care for the SQL included in the class files.

Personally, I don't have a huge problem with it, but I understand the concern that others have. It definitely violates separation of concern, instead favoring encapsulation. Good or bad, that's the way it is.

But the more I thought about it, the more I wondered how hard it would be to create a simple interface to create your own queries easily. And then I started building it. By the time I was done, I had a solution in place that allowed me to create all of the queries created by the Kinetic Framework, and cover the majority of custom cases. And it has at least a bit of a fluent interface!

For custom queries, this is what we had before (this is from an example of getting a game with team's real names - there's a number of joins in there):

   1:  string commandText = @"
   2:  select " + Game.SelectFieldList + @",
   3:      [" + Week.TableName + @"].[Number] as 'WeekNumber',
   4:      ht.[Location] + ' ' + ht.[NickName] as 'HomeTeamDisplayName',
   5:      at.[Location] + ' ' + at.[NickName] as 'AwayTeamDisplayName'
   6:  from [" + Game.TableName + @"]
   7:  inner join [" + Week.TableName + @"]
   8:   on [" + Game.TableName + @"].[WeekId] = [" + Week.TableName + @"].[WeekId]
   9:  inner join [" + Team.TableName + @"] ht
  10:   on [" + Game.TableName + @"].[HomeTeamId] = ht.[TeamId]
  11:  inner join [" + Team.TableName + @"] at
  12:   on [" + Game.TableName + @"].[AwayTeamId] = at.[TeamId]
  13:  where [" + Game.TableName + @"].[SeasonId] = @SeasonId 
  14:  order by [" + Week.TableName + @"].[Number] asc;
  15:  ";
  16:   
  17:  List<IDataParameter> parameters = new List<IDataParameter>();
  18:  parameters.Add(ServiceLocator.GetDataParameter("@SeasonId", season.SeasonId));
  19:   
  20:  return EntityBase.GetList<FullGame>(commandText, parameters);

Notice the large string built and manually working with parameters. Lots of SQL syntax knowledge involved here.

Compare that to the way I came up with:

   1:  JoinCriteria joinCriteria = new JoinCriteria(typeof(Game), typeof(Week), 
   2:      Game.GameProperties.WeekId, Week.WeekProperties.WeekId)
   3:    .Add(new JoinCriteria(typeof(Game), typeof(Team), 
   4:      Game.GameProperties.HomeTeamId, Team.TeamProperties.TeamId, "ht"))
   5:    .Add(new JoinCriteria(typeof(Game), typeof(Team), 
   6:      Game.GameProperties.AwayTeamId, Team.TeamProperties.TeamId, "at"));
   7:   
   8:  ICriteria criteria = new StandardCriteria(typeof(Game), Game.GameProperties.SeasonId, 1);
   9:  IQueryContainer query = (new QueryGenerator(typeof(FullGame), criteria, joinCriteria)).GetQuery();
  10:  return EntityBase.GetList<FullGame>(query.CommandText, query.Parameters);

I'm not sold on the exact semantics yet, but the idea is there. This doesn't require any SQL knowledge. You still have to know how your objects are related, but not SQL directly, and you don't have to worry about creating your own parameters. The QueryGenerator handles creating the query for you, and as it builds the query, it maintains the parameters as well.

The other nice thing about this is that, while it is meant to work with the Kinetic Framework, it doesn't require any changes to the framework to work - it's essentially an add-on that I could plug into any of my existing projects and immediately get the benefit of being able to build queries quickly and easily.

I've also been messing around with the ASP.NET MVC bits as well. I'm trying to figure out how I could use that with the Kinetic Framework, and be able to unit test the controllers. Because of all of the static Get methods, that's tough. So I've been messing around with the idea of adding Repositories to handle the actual retrieval and persistence of the entities. It's still a bit awkward, but I was able to unit test my controllers without ever hitting any of the static methods or any persistence methods in the framework - because I was able to mock my repositories. I need to tighten that up a bit, but I'll probably blog about that a bit in the future. Actually, the above querying technique makes the repositories easier to create and less coupled to the static methods in the entities - a good thing. But that's for another time.

So, if you use the Kinetic Framework, would this be something you'd be interested in? It still needs a lot of work, but I wanted to see if there's any interest in it before I pursue it too much.

Category: C#, RCM Technologies

Leave a comment


 

Simple Online CMS

posted on 08/13/08 at 08:00:00 pm by Joel Ross

Ever since I started this site, I've been trying to figure out a way to simply manage a few items and pages - such as my about page. I know I could have done a blog post that included my about information, and then just linked to that, but it seemed like a hack, and the URL wouldn't be as clean.

So I created a static page - well, relatively static. It's still a page using my blog's template, but the main content area is static content instead of code that pulls in blog posts. But even so, it's a pain to maintain. I have to edit locally and then upload the files. And it's all maintained in a virtual machine, so it's even more of a pain.

Ok. So it's not that bad. I'm just lazy.

But the other day, I saw a tweet from Cisco, a fellow RCMer, mentioning CushyCMS. You see, Cisco's a designer who is very good at what he does, and if he's saying something is good, that means it's well designed, has good usability, and doesn't take any technical knowledge whatsoever.

Yeah, yeah. That last one wasn't fair. But in this case, it's true. CushyCMS offers you online HTML editing of any page on your site. It's simple to set up and it works well. I have one page under its control now, and am thinking of adding others - or at least parts of others.

What it's actually doing is pretty simple - it uses FTP to push the file back to the server. But the ability to edit online from anywhere in a WYSIWYG fashion is killer. And I can segment my page anyway I want - just add a class="cushycms" to any element and it's editable. Below, I've added the class to an H3 (About RossCode.com), a div around some content, and then to another H2, and an H3 below that. They all show as editable areas:

CushyCMSedit

In the past, I've hesitated to add a blog roll to the sidebar, because it's too difficult to maintain - or really any manually maintained areas there that I would want to change. But now, I could add some of those types of features and manage them easily, preventing them from getting out of date.

As I was writing this post, I was also tweeting my experience. Nathan Bryan responded that it's a problem when you keep files under source control. While this is true, I think some of it depends on how you use it. If you're adding CushyCMS directly to your code files, then yeah, that's a problem. But CushyCMS recommends against that anyway, instead recommending that you store the content you want to edit in a static file by itself. Then you just include that content in the dynamic page where you need it. To me, this isn't really that much different than storing your content in a database - something most CMS systems do - and then working out a backup process for those custom files.

CushyCMS probably isn't something to use for a large site, but for small, one-off solutions, it looks like a good, easy to integrate solution that solves a common need.

Category: Software

1 comment


 

Getting Started With Mocking and Moq

posted on 08/08/08 at 12:45:40 am by Joel Ross

Lately, I've taken a keen interest in unit testing. I've started to rewrite some of my code to make it more test-friendly. One of the frustrating parts about doing that is that I found I was creating a lot of fake classes in my tests so that I would be able to test just a single part of my code, while holding other parts constant.

Maybe it's just because I always envisioned that testing would be pretty simple, but for some reason, having all of those extra (fake) classes around didn't sit well with me. So I decided to look into a mocking framework. Since I was using .NET 3.5 and I'd heard that Moq was built on that, I figured I'd give that a go. It's worked out quite well.

Imagine that I have a User class:

   1:  public class User
   2:  {
   3:     public FirstName { get; set; }
   4:     public LastName { get; set; }
   5:     public UserName { get; set; }
   6:     public Password { get; set; }
   7:     public Email { get; set; } 
   8:   
   9:     public User() { }
  10:   
  11:     public bool EmailPassword(IEmailSender emailSender)
  12:     {
  13:        string subject = "Your Password";
  14:        string body = String.Format("{0} {1}, your password is {2}", FirstName, LastName, Password);
  15:        return emailSender.Send(subject, body, Email);
  16:     }
  17:  }

One of the things you'll notice about code written to be tested is that it's very modular, so when a user requests their password, the User class doesn't know anything about how an email is sent - it just uses an interface, and it's up to the calling application to supply that. If you start to write all of your code this way, you'll quickly see the usefulness of using a dependency injection framework (such as Ninject) to handle resolving your dependencies for you. But that's not what I'm focused on here. As a matter of fact, I don't care about the actual implementation of IEmailSender that the application will use. All I care about is the interface:

   1:  public interface IEmailSender 
   2:  {
   3:     bool Send(string subject, string body, string email);   
   4:  }

If I want to test the EmailPassword method, I have a couple of options. I could create my own mock email sender and implement the Send method and have it return true. But what happens when I want to test what happens when it returns false? Or it throws an exception? Now I'm starting to write a lot of code in a fake implementation, strictly for the purpose of testing. While I think the benefits of doing that are there, I also think there's potentially a better way.

The second option is to use a mocking framework. When you work with a mocking framework, what you're doing is essentially implementing the interface on the fly, and telling it what it should return when methods are called. Let's look at an example of a test that just verifies that EmailPassword returns true when emailSender returns true:

   1:  [Test]
   2:  public void User_Can_Send_Password()
   3:  {
   4:     var emailMock = new Moq.Mock<IEmailSender>();
   5:     
   6:     emailMock
   7:        .Expect(sender => sender.Send(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
   8:        .Returns(true);
   9:     
  10:     User user = new User();
  11:     Assert.That(user.EmailPassword(emailMock.Object) == true);
  12:  }

Line four says that I want to create an implementation of the IEmailSender interface, so I can use that later in line 11, when I call EmailPassword. Notice the .Object - that's the dynamically created IEmailSender. Lines six, seven and eight are the meat of the mock. Line seven sets up how the mock should expect to be called. Any time Send is called, passing in any string for any of the parameters (the It.IsAny<string>() code), line eight specifies that it should return true.

Now if we wanted to verify that EmailPassword returns false when IEmailSender.Send returns false, it's just a matter of taking the above code and changing line eight to .Returns(false). Each test sets up the mock the way it wants, so the mock is isolated across tests. There's no need for any extra logic to determine what should be returned in scenarios beyond the scope of that test, like there would be if I created an actual MockEmailSender to cover all of the different cases.

There are different options with the expects (in line seven) to allow you to match that the correct parameters are passed as well. You can also add a .Verifiable() on the end of the mock setup code and then call emailMock.Verify() after you run your test code (so, after line 11) and verify that the method was actually called.

I'm still fairly new to Moq and mock objects in general, but so far, I'm impressed with what I've been able to do and how quickly I can do it.

Category: Development, C#

1 comment


 

An Interesting Summer Ahead

posted on 07/24/08 at 12:55:37 am by Joel Ross

A little over a week ago, The Wife headed out to the garage to get us some dessert. When she came back into the house, she was pretty excited - she found some moose tracks ice cream - and she came flying up our back stairs (there's 4 of them).

"Joel! I just broke my foot!"

I looked toward the back of the house, and she was standing on the stairs - on one foot, holding the other one. She can be a bit dramatic, so I didn't think too much of it. She tells me that she's broken a bone on a fairly regular basis, and after "toughin' it out" for a little bit, it's usually just fine.

But this was different. She wasn't putting her foot down, and she wasn't moving. So I headed down there and helped her to a stool in the kitchen. Then I went to get a neighbor to help get her to the car. We had the neighbors watch the kids (I love my neighbors - they are ALWAYS willing to help us out when in need), and we were off the ER.

Once at the ER, I got to hear what happened from her perspective. Get ready to cringe. As she was coming up the steps, she felt her foot start to slip (she was in a pair of flimsy flip-flops). This isn't anything new for her, but usually she slips down and bangs her shin on the step. She didn't want to hurt her shin again, so she gripped down on her foot. But she wasn't fully on her foot - just the end of her foot was step. She pushed down, and when she was done, she knew something was wrong. When she looked down, she could see her bones sticking up in her foot. Not through the skin, but she knew it wasn't right. Before the pain kicked in, she reached down and pushed the bones back into place!

After 4 long hours, excruciating pain (she said this was the worst pain she ever felt, which is telling given that she's given birth to three kids), X-Rays and a CT, the doctors came to the same conclusion it took my wife two seconds to come to: Her foot was indeed broken. The prognosis was basically that she folded her foot in half. She was given some Vicodin and a splint and sent home on crutches.

We went to a local doctor a few days later. He essentially told us that she broke bones in 5 places and would be off her foot for 3 months, but no surgery at this point. They'd re-evaluate on a bi-weekly basis, and with that, we were done - 5 minutes with the doctor. The Wife wasn't comfortable, so we decided to get a second opinion. In that five minutes, he did tell us that it was "a very bad and very serious injury" so we felt justified getting a second opinion. Of course, we were pretty sure it was a bad injury since, you know, you're not meant to fold your foot in half!

The second doctor was far, far better than the first. He sat with us for about an hour explaining everything. We actually got to see the X-Rays - he was impressed that the ER picked up on what happened, but his diagnosis was completely different than the other doctor's. He said that yes, there were either 4 or 5 bones broken, but that wasn't the concern. Those would heal as part of treating the real issue. What she actually did has a name: The Lisfranc Injury. Apparently it's actually quite often missed in diagnosis - that article says as many as 20% are missed.

He gave her two options - surgery or no surgery. He gave us all of the pros and cons of each, and left it up to her. He said she would never forget that she broke her foot, and that most likely, it would never be solid enough to withstand the rigors of the NFL (his examples of other people who had the same injury were Duce Staley and Aaron Brooks), so I guess that means her NFL career is over! The good news was that he thinks the recovery time (surgery or not) would be 6-8 weeks, rather than 12. And he made it more comfortable for her to sleep. Based on the pros and cons, she opted out of surgery, and I think it's a good decision.

While she's healing, she's essentially stuck on the couch. She can't put weight on it, and using the crutches requires two hands. She can't really pick up or carry our 11 month old son, who is taking it pretty hard - mommy can't be mommy right now. Frankly, it's hitting all of us pretty hard, but we'll make it through.

One last thing: I told my oldest it was time for bed the other night, and that she had to get off the cough. She told me she couldn't because "mommy's crotches are in the way." I'm almost positive she meant crutches!

Category: Personal

6 comments


 

The NuSoft Framework Is Now The Kinetic Framework

posted on 07/16/08 at 09:32:59 pm by Joel Ross

One of the first questions I got when people heard about RCM bought NuSoft Solutions was whether we were going to be renaming the NuSoft Framework. At the time, I had no idea, and frankly, it was about as far back in my mind as it could be.

Well, the acquisition is three months in the past, and we're starting to integrate things tighter now. As part of that, there was concern about brand confusion with RCM using and sponsoring the NuSoft Framework. So, the decree came down to rename the framework.

Which we did. Since we've started a new group - Kinetic IG - it was only natural to lean towards the Kinetic Framework, but that's not the only reason we settled on that name. The framework has two important aspects that relate to the word "Active" (of which Kinetic is a synonym). First, it uses the Active Record design pattern for it's entities. Second, it relies on active code generation - the majority of the code generated can be re-generated if your data model ever changes without wiping out any custom code you may have. Given those things, combined with the idea of kinetic having to do with motion and momentum, we felt it was a good name.

We've updated the CodePlex address to http://www.codeplex.com/KineticFramework, but the old address does redirect to the new one. I am in the process of changing all of the content and source to reflect the name change - I would expect to be done in the next few days.

As far as framework development goes, not much has been going on. I have been playing with it a bit to make it more testable, but nothing official yet. More on that if I ever get it to a place where I'm happy with it.

Category: RCM Technologies

Leave a comment


 

Testing the NuSoft Framework

posted on 07/09/08 at 12:45:25 am by Joel Ross

NuSoftFrameworkI've started up a new project that is using the NuSoft Framework, and because of some of the interactions, I realized it would be much, much easier if I had a set of automated tests, rather than going through the process of firing up an application, going through a WCF service, and then eventually hitting the code I needed to test.

I realize this isn't earth shattering for those used to doing TDD or unit testing, but it's not something that I've done a lot of in the past. On one project, we had well north of 100 tests, but they were all isolated to a particular hairy part of the code and it was rather self-contained.

To be honest, the NuSoft Framework is not ideal for unit testing, since the data persistence is pretty well embedded into the entities. That's OK in my mind, since I've rarely seen a case where my persistence layer has changed. Once, I knew I had to build for different databases, but that was known up front, and not added after the fact. That may be viewed as a naive attitude, but it's worked for me so far.

Anyway, there's a reason I didn't call this "unit testing" but rather referred to it as just testing. It's not unit testing, since it's not testing just one thing. It's more like an integration test, since it's also going to rely on a known state of the database.

Essentially, what you have to do is manage your own transaction, and then at the end, after you assert that your desired action worked, you roll it back, leaving the database untouched. If you want to isolate your tests in their own assembly, you're going to need to add an attribute to your business layer so you can gain access to some of the internals of the business layer:

   1:  [assembly: InternalsVisibleTo("Northwind.Tests")]

This gives us the ability to call one of the internal overloads on Save() where you can pass in a helper. This ensures the Save will participate in the existing transaction, and not create its own (which it does when you call Save() with no parameters). Here's an example that would test being able to insert a customer:

   1:  [Test]
   2:  public void CanInsertCustomer()
   3:  {
   4:    Customer customer = Customer.CreateCustomer();
   5:    customer.CustomerId = "jross";
   6:    customer.FirstName = "Joel";
   7:    customer.LastName = "Ross";
   8:   
   9:    using (SqlHelper helper = new SqlHelper())
  10:    {
  11:      try
  12:      {
  13:        helper.BeginTransaction();
  14:        customer.Save(helper);
  15:        Assert.That(customer.IsNew == false, "customer.IsNew was true but should have been false.");
  16:      }
  17:      finally
  18:      {
  19:        helper.Rollback();
  20:      }
  21:    }
  22:  }

The difference between this code and the code you would normally use is that you wouldn't manage your own helper and you'd call customer.Save(), not customer.Save(helper). If you dig into the guts of Save() with no parameter, you'll see it does essentially what I'm doing here. It creates a SqlHelper and opens the transaction. The difference is that if the insert works, the transaction is committed, and here the transaction is always rolled back, ensuring that the database isn't affected and leaving it in a known state for other tests.

I'm still new to automated testing, but it definitely does make being able to change existing code much easier and give me more confidence when I am doing that. And seeing all of the green lights in NUnit feels pretty good too.

Oh - the NuSoft Framework has a logo now (the one at the top of this post). What do you think of it?

Category: Development, C#, RCM Technologies

5 comments


 

Grand Rapids Tech Lunch – Monday July 7th

posted on 07/01/08 at 09:26:45 am by Joel Ross

The second Grand Rapids Tech Lunch has been announced, and it'll be at the Grand Rapids Brewing Company on July 7th at 12:00 PM. We have their private room reserved, so it should be a bit quieter than last time, and maybe we'll all fit around the same table!

I'll be there, and hope to see a few people from the West Michigan area there as well!

Tags:

Category: General

Leave a comment


 

The Saga of the Dell D820 and 4 Gigs of RAM

posted on 06/30/08 at 09:35:29 pm by Joel Ross

Two summers ago, I got a new laptop - the Dell Latitude D820, a nice dual core machine that works great for what I do - software development. The only issue I had with it was RAM. It came with 2 GB, but that wasn't enough for me. I do all of my development in Virtual PC, and sometimes have 2 or 3 open at a time. Even with only dedicating 512 MB RAM to the virtual machine, my laptop would grind to a halt.

So I upgraded to 4 GB - the price was great ($200 for 2 2 GB sticks). After installing it, I was a bit disappointed to see that the BIOS only exposed 3.325 GB to the OS, but still - I had an extra 1.325 GB of RAM, and I could run 2 VMs, with each getting 1 GB RAM - and the machine still responded well. I figured eventually there'll be a BIOS update or something that would allow me to get that last bit of RAM!

Well, a couple of weeks ago, that BIOS update was supposedly released. It wasn't verified, but word was that the A09 revision could give you access to the full 4 GB. After a bit of a hassle (Ok - it was a MAJOR hassle, but that's not the point here), I got it installed.

So did it work? I honestly don't know yet. I checked Task Manager, and this is what I see:

TaskManager

I saw this (Total still at 3.325 GB), and was mildly disappointed. Not shocked, but disappointed. I found an article that talked about enabling PAE, and then it showed (after you enabled it) a screen shot that you can get by right clicking on "My Computer" that shows the full 4 GB. So I tried that. This is what I see:

MyComputerProperties

So now, I'm confused. Do I have 4 GB or not? I know what I want to believe, but what's the reality?

Category: General, Software

6 comments


 

NuSoft Framework Now Included with CodeSmith 5.0

posted on 06/29/08 at 08:00:00 pm by Joel Ross

CodeSmith announced recently that version 5.0 is in beta, and one of the features listed is that it now includes the NuSoft Framework right in the download! That's pretty exciting, as we never expected that when we first started writing our templates.

There's actually a whole bunch of templates included now, including NHibernate and .NetTiers ones. I've found that the templates are a great source of sample code to write your own templates - mess around with them and figure out exactly how someone else solved the problem you're trying to solve.

The feature I'm really excited to try out is the source control integration - that running CodeSmith projects from within Visual Studio will cause checkouts to occur. That's a nice change, and will make it easier to keep my generation right inside of Visual Studio - something that I hadn't been doing.

It's still in beta, but I plan to give it a go soon - and provide feedback for one of my favorite development tools.

via Rob Howard

Tags: | |

Category: Development, Software, RCM Technologies

Leave a comment


 

War Room and Their Proper Place

posted on 06/26/08 at 08:00:00 pm by Joel Ross

WarRoomThe other day, Matt Blodgett made a few comments about War Rooms, wondering whether they were actually helpful, or if they did more harm than good. In the interest of full disclosure, I should mention that I work with Matt at RCM, so I have some background on what he's been up to. His project team has been holed up in a room for a few months now. It seems like every time I'm in the office, I see members from his team bringing in supplies (read caffeine, usually in the form of pop - or soda for you southerners!). I stopped by the office on a Saturday, and a subset of the team was there - they're always in there!

Anyway, I piped up that War Rooms, when used in moderation, can be extremely useful.

Let's back up for a second and look at what a War Room is. I haven't heard the term "War Room" thrown around in software development that much, but we use them a LOT at RCM. So I decided to do a bit of research and see what it means and where it came from. Here's how Dictionary.com defines War Room:

1. a room at a military headquarters in which strategy is planned and current battle situations are monitored.
2. any room of similar function, as in a civilian or business organization.

War Rooms got their start, not surprisingly, in the military. I picture a typical War Room as a group of Generals sitting around a table with each getting information fed to them from the field. Then they share that information with each other, and form a high level strategy that gets sent out to the field to be implemented. The field teams implement the new plan, and report back on progress. The process is repeated, until the war is either won or lost.

RCM is not a military organization, so we're not trying to win any wars. We fall under the second definition, and for us a war room is a room in which strategy is planned and current situations are monitored. Or at least that's the intent is.

In reality, War Rooms, for us anyway, have been used as a place for developers to all work in the same room, so that communication is easier. That sounds good, but in reality, it becomes a distraction, because any major debate results in pulling the whole team into the discussion. Those rarely end well. The discussion usually pits two of the development leaders against each other, and, under normal circumstances, they would work out their differences and present a unified front to the team. When the disagreement is public and in front of the whole team, it makes backing down more difficult. Saving face becomes the priority rather than finding the Right Solution. And no matter what the outcome, the team loses faith in their leadership, because of it's perceived fracturing at the top.

I've been on a couple of projects that have effectively used War Rooms. When they're used correctly, they can have a huge benefit. Some research suggests they can double efficiency. But constantly holing up in a room for months at a time doesn't seem like the best way to me. What we've done is move people's desks to a certain area of the office, so the whole team can be close, but not necessarily stuck sitting around a table. The room is reserved for what a War Room was intended - strategic planning and tactical discussions. We use it to flesh out our plan for the next iteration - high level design with just the parties that need to be involved. Tasks are assigned and then everyone disburses back to their desk to actually do the work. We meet up weekly to sync on tasks and more often if needed for a particular component.

Besides weekly meetings, about the only time the whole team actually gets together in the War Room is after we're pretty much functionally complete for an iteration. Those typically involve lots of back and forth between sub-teams and the QA team. Because of the rapid nature that issues are found and fixed at that point, it's imperative that we're able to work close together. Because the stints are usually short - 2 or 3 days at the most - people don't get burned out being in there, and we usually get a lot accomplished while having a good deal of fun. The free lunches don't hurt either!

The best arrangement for a physical team structure is to have the War Room close to the team's desks. That way, you can quickly get in there, and if the room is dedicated to your team, you don't have to worry about it being used - even if the room sits empty sometimes. It's more difficult if the room is physically separated from your team's desk area, but still workable. Back in the Sagestone days, we had at least one conference room physically close to desks, and we would move teams to that area while the project was going on. At RCM, we don't have conference rooms close to the cube farm, so it makes it more difficult, but we still can move desks to get teams closer, and that definitely helps.

Anyway, I definitely see the value in War Rooms - but I think they are much more effective when used in moderation.

War Room photo courtesy of John Beagle

Tags: |

Category: Consulting, Development, Software

4 comments


 

The Art of Software Estimation

posted on 06/25/08 at 12:35:16 am by Joel Ross

I suck at estimates. I know that, and when I have to do them, I use a spreadsheet that gives me a fudge factor for my numbers. Or, to be more precise, my estimates tend to be how much time it'll take to do the initial development, and there are percentages added on for QA, design, and project management - all of the non-development time that I try not to think about, as well as time for bug fixes (not that there's ever bugs in my code!). I've never really figured out exactly how time is added on (and it changes as new spreadsheets get sent out), but I have been reading "The Mythical Man Month", which is a great book. Anyway, it states that development time is actually 1/6 of the overall time - so my 5 hour estimate should actually result in 30 hours on the project. I'm pretty sure our spreadsheet isn't that extreme, but I also include a bit of design in that development estimate.

To be fair, The Mythical Man Month was written in the 80's (I think) and software development has changed quite a bit since then, so the numbers could be different now. The idea still remains - if done correctly, the development effort shouldn't be the major time sink. But, as I've looked around, there's one thing that I haven't seen included in any estimation system. It's illustrated by a quote from the book.

Extrapolation of times for the hundred yard dash shows that a man can run a mile in under three minutes.

We tend to look at software estimates as successive hundred yard dashes instead of a long distance race. It allows a client to pick out just what they want built, while using their line item veto on tasks they don't want to do. But this assumes that you can break a software system down into features that have no interactions. A series of silos, though, isn't an accurate description of software. There's interactions between features, and rarely do you see estimates take that into account.

This applies to velocity as well. Velocity is the measure of how many features you are delivering over a period of time. When does a project have the highest velocity? My experience has been that it comes right after your base framework is in place and you're building out the first few features. It slows down over time, until the end, when velocity pretty much slows to zero before launch - you're not delivering new features at that point. You're only stabilizing what's already been built.

Why does that happen? Well, to answer that, consider this example. When would it be easier to create an order entry system: Before or after the back-end order fulfillment system is created? It's before, because you don't have to integrate the two processes when the other isn't created yet - you stub it out the way you think it'll work. Even if you do have a task specifically for the integration between the two, it's more time consuming to build something against existing constraints than it is to build something without constraints. And if two teams build them simultaneously, rarely can you just put them together and have it work - there's almost always slight differences in how the two teams interpreted the spec. But the estimate doesn't typically take that into account, meaning there's time to reconcile the differences that isn't in the estimate.

I'm not sure how you would even go about taking that type of time into account. A factor of time that grows as the number of features grows? As the base timeline grows? I don't know. It just doesn't seem logical to think of software development as a series of 100 yard sprints, when in reality, we need to look at it as a marathon - otherwise, it will become a much, much longer and tougher marathon!

When you create your estimates, is it a series of 100 yard dashes, or is it a long distance run?

Tags: |

Category: Consulting, Development

5 comments


 

A Few New Podcasts I’m Excited About

posted on 06/18/08 at 08:00:00 pm by Joel Ross

It seems like everyone and his brother has started some sort of podcast recently, and since I'm an avid podcast fan, I've added a few to my list. The crazy thing about this list is that I knew the people doing each of the podcasts before they started doing it. Maybe not directly, but they are a part of my twitter tribe, which counts in my book!

First up is Deep Fried Bytes. It's hosted by Chris Woodruff, who works with me at RCM, and Keith Elder. It's only had a few episodes so far, but they've all been very good and entertaining. I know these two guys, and I'm looking forward to see what the show becomes. Despite only having three episodes so far, it's produced very professionally.

Next is the ALT.NET Podcast. The more I look at the whole ALT.NET movement, the more I wonder if I would be considered a part of it, for various reasons. But I definitely agree with the premise behind it (if not necessarily it's implementation). The podcast, so far, has been about the part I can relate to, and the guest list so far has been excellent. It's hosted by Mike Moore and he does a great job with it.

The Technology Round Table Podcast (that's as close as a link as I can come up with) is an interesting one. It's a round table (virtual, of course) where they talk about the latest news. It's got four really smart guys on it, and at least right now, it doesn't have a dedicated site or RSS feed. But that doesn't disqualify it! The four smart people are Jon Galloway, Scott Koon, K. Scott Allen and Kevin Dente. They're currently looking for a name, and I think I'm leaning towards "Four Horseman Podcast".

Dime Casts.Net is the only video podcast on the list, and Derik Whittaker's goal is to teach a single concept in under ten minutes. Some of the concepts are pretty simple and some are more complex, but they are all very well done so far. And because it's only 10 minutes long, it's easy to find the time. And even the beginner topics are good reviews for most.

I know there are other new podcasts out there, and I know of at least one on the horizon that sounds interesting, but for now, those four are the ones I'm watching closely right now.

Tags:

Category: Podcasting

7 comments


 

Ninject Hits 1.0

posted on 06/16/08 at 09:47:32 pm by Joel Ross

My favorite DI framework, Ninject, has just hit 1.0. Nate Kohari, the author of Ninject, has been working hard on it, and today, announced that it's gone gold. Congrats, Nate!

A few months back, I wrote a post about how dependency injection helped me write code that was more flexible than hard coding the dependencies. In the comments, the discussion of using a framework came up, and I decided to give it a go. I asked what framework I should use on Twitter, and the consensus was Windsor. But later, I had a discussion with Nate, who wasn't around when I asked, and I decided to replace my Windsor implementation with Ninject. It took more time to download Ninject than it did to get it implemented!

Ever since, I've been a huge fan. It's extremely easy to use, and Nate is easy to talk to, and actually listens to your feedback. So, if you're in need of DI (and you should be!), check out Ninject. It's definitely worth your time!

Tags: |

Category: Software

Leave a comment


 

Performance Tweaks For Your Cache

posted on 06/13/08 at 08:00:00 pm by Joel Ross

Over the past few weeks, I've been dealing with a performance issue on Tourneytopia. The site has been working as expected, but it's been a bit slower than I think is acceptable. So we decided to take a look and see if there's a better way to do things that would speed it up.

One of the areas we found was with how we cache data. We cache results fully scored and ranked, which is fine. The problem lies in how we were populating the cache. It's something we would never notice in development, because when you're just firing up the debugger, you aren't running multiple threads against that code. It's only when you hit the same code on multiple threads do you notice the issue. Here's how our cache was working:

   1:  public List<ScoredEntry> GetScoredEntries()
   2:  {
   3:    if(HttpContext.Current.Cache["ScoredEntries"] == null)
   4:    {
   5:      HttpContext.Current.Cache["ScoredEntries"] = Pool.GetScoredEntries();
   6:    }
   7:    return HttpContext.Current.Cache["ScoredEntries"] as List<ScoredEntry>;
   8:  }

At first glance, this looks just fine. The first time this code is exercised, the cache is null, so we populate it. Then we return it. Nothing wrong there, right? Well, yes, actually. Pool.GetScoredEntries() takes time to complete. While it's running, what happens if another thread hits this code? The cache is still null, so it tries to populate it, meaning it calls Pool.GetScoredEntries() again. Now imagine 50 threads come through. See the problem?

So we needed a way to signal that Pool.GetScoredEntries() was already running, so no other code would run it. As it turns out, that's what the lock keyword is for. After implementing it, this is what our updated code would look like:

   1:  private static object _cacheLock = new object();
   2:   
   3:  public List<ScoredEntry> GetScoredEntries()
   4:  {
   5:    List<ScoredEntry> entries = HttpContext.Current.Cache["ScoredEntries"] as List<ScoredEntry>;
   6:    if(entries == null)
   7:    {
   8:      lock(_cacheLock)
   9:      {
  10:        entries = HttpContext.Current.Cache["ScoredEntries"] as List<ScoredEntry>;
  11:        if(entries == null)
  12:        {
  13:          entries = Pool.GetScoredEntries();
  14:          HttpContext.Current.Cache["ScoredEntries"] = entries;
  15:        }
  16:      }
  17:    }
  18:    return entries;
  19:  }

A couple of things to note. First, we have a private static object declared. Second, we lock that object if the cache is null. The check for null inside of the lock() is because you could have a situation where while the lock is being obtained in one thread, another thread could hit the if statement and have it be true. Then the first thread would gain the lock, populate the cache, and release the lock. Once the second thread obtained the lock,  line 10 will actually return the correct results. No need to repopulate the cache - that's the situation we were in before!

Also, one last thing about this code. I introduced a local variable (entries) that wasn't there before. I probably should have that in the original as well, because there's a slight possibility that in the time that I check if the cache is null and then grab the value out of cache, the entries could have been thrown out of cache. By using a local variable, I ensure that if that happens, it doesn't affect me.

Now, this code isn't exactly what we have for Tourneytopia. I don't use magic strings, nor are my methods that simple to call. And we don't have just one cache lock object. Because scoring (and thus, cache) is by pool, I have a method that gets the correct object to lock, based on a key, which is in turn based on a pool. That actually has its own lock object:

   1:  private static object _cacheSetter = new object();
   2:  private static Dictionary<string, object> _cacheLockList = new Dictionary<string, object>();
   3:          
   4:  private object GetCacheLockObject(string key)
   5:  {
   6:    if(_cacheLockList.ContainsKey(key))
   7:    {
   8:      return _cacheLockList[key];
   9:    } 
  10:    else
  11:    {
  12:      lock(_cacheSetter)
  13:      {
  14:        if(!_cacheLockList.ContainsKey(key))
  15:        {
  16:          _cacheLockList.Add(key, new object());
  17:        }
  18:        return _cacheLockList[key];
  19:      }
  20:    }
  21:  }

The _cacheSetter object is locked only long enough to create the necessary cache lock object, which is by key. Then in my cache retrieval methods, I lock on that object. If there's an object already there for that key, it's returned. Otherwise, the global lock object is locked and the new object is created and added to the dictionary for that key.

Now, the same lines of code can be run by multiple threads for different pools, and not lock each other out, which is what we want, because in reality, they're actually setting different caches. This makes my GetScoredEntries look a little different:

   1:  public List<ScoredEntry> GetScoredEntries(string key)
   2:  {
   3:    List<ScoredEntry> entries = HttpContext.Current.Cache[key] as List<ScoredEntry>;
   4:    if(entries == null)
   5:    {
   6:      lock(GetCacheLockObject(key)
   7:      {
   8:        entries = HttpContext.Current.Cache[key] as List<ScoredEntry>;
   9:        if(entries == null)
  10:        {
  11:          entries = Pool.GetScoredEntries();
  12:          HttpContext.Current.Cache[key] = entries;
  13:        }
  14:      }
  15:    }
  16:    return entries;
  17:  }

Instead of locking on just one global object, we call GetCacheLockObject to get the actual object to lock.

Lots of tweaks involve making code run faster, This particular one has nothing to do with optimizing the code - it's all about making the code smarter so there aren't multiple instances of the same code running at the same time.

Tags: |

Category: Develomatic, Development, C#

3 comments


 

Url Rewriting And Form Actions

posted on 06/11/08 at 08:00:00 pm by Joel Ross

I have been working on a site for the past couple of months, and as part of that, we wanted to make our URLs prettier and more "hackable" - users are easily able to figure out how to get to the info they want.

Well, we ran into an issue with that. The page we rewrite to has a form on it and when that form posts back, we get Viewstate validation errors. That's a problem! Basically, the form has the wrong URL in the action, and we needed to somehow change the form's action.

Not that I'm surprised, but ScottGu already knows the solution. Towards the end of his post is a section titled "Handling ASP.NET PostBacks with URL Rewriting" and he mentions the problem I was seeing. He even has the source control for the form control adapter that solved our problem. It's written in VB.NET, and I needed it in C#, so I ported it. Here's the port:

   1:  public class UrlRewriterFormWriter : HtmlTextWriter
   2:  {
   3:    public UrlRewriterFormWriter(HtmlTextWriter writer) : base (writer)
   4:    {
   5:      base.InnerWriter = writer.InnerWriter;
   6:    }  
   7:    
   8:    public UrlRewriterFormWriter(System.IO.TextWriter writer) : base(writer)
   9:    {
  10:      base.InnerWriter = writer;
  11:    }
  12:   
  13:    public override void WriteAttribute(string name, string value, bool fEncode)
  14:    {
  15:      if (name == "action")
  16:      {
  17:        HttpContext Context;
  18:        Context = HttpContext.Current;
  19:   
  20:        if (Context.Items["ActionAlreadyWritten"] == null)
  21:        {
  22:          value = Context.Request.RawUrl;
  23:          Context.Items["ActionAlreadyWritten"] = true;
  24:        }
  25:      }
  26:      base.WriteAttribute(name, value, fEncode);
  27:    }
  28:  }

The code isn't that complicated. Basically it looks for attributes named "action". Once it finds one, it updates the action to be the RawUrl - the pre-rewritten Url. Then it ensures that it doesn't do anything else (the ActionAlreadyWritten part). That way, the post backs work, and the "pretty Url" stays in the browser's address bar.

To use this class, you just override Render:

   1:  protected override void Render(HtmlTextWriter writer)
   2:  {
   3:    base.Render(new UrlRewriterFormWriter(writer));
   4:  }

That's it! Now your Urls stay pretty, and it got rid of our nasty viewstate issues.

Tags: | |

Category: Development, C#

Leave a comment


 

Essential Development Practices

posted on 06/09/08 at 09:27:09 pm by Joel Ross

Over the past month, I have been helping a client establish a solid and reliable environment for team development. To be honest, I'd heard stories about poor development environments, but it was just theory and for all I knew, it could have been "Straw man" type argument meant to demonstrate the importance of certain development practices. You couldn't actually be doing team development without source code, right?!?

Well, I can now say that it is possible - I've seen it with my own eyes. The good news is that they were fully aware of the problems, but when you're heads down day in and day out fixing issues and developing features, it's tough to get your head above water and get a few things in place - even if it will make life easier in the long run.

At some point, they knew they needed some better practices, but didn't have the time to put it together themselves, so I was tasked to help them out. In the course of just a few hours, we were able to get source control and issue tracking in place. This included importing their source, and a brief training on the basics of checking in and checking out.

The project is still on-going, and we have a few more things that we want to do, but this whole process got me thinking about what I consider to be the "no brainers" of software development - the things that you use on every project that you just take for granted. Of course, this reminded of a post by Russell Ball where he listed out his seven essential practices.

For me, the absolute, bare minimum I expect on projects I work on are source control, issue tracking and continuous integration. There are other niceties, but without those three things, I'd rather not work on the project. I feel so strongly about those three that I ensure that even for personal projects, I have all three in place. Sometimes for personal projects, issue tracking may be as simple as a wiki, but the point is that I have something. CI is such a critical piece to me that I've implemented it on projects in my spare time - and I usually end up saving time down the line because deployments are easier and I know the code at least builds at all time (or why it doesn't!).

So, what are your absolute bare minimums before you'll say that you'd rather sit and be idle then develop in those conditions?

Category: Consulting, Development, Software

2 comments


 

How NOT To Get Bloggers To Help Your Company

posted on 06/07/08 at 10:17:16 pm by Joel Ross

The other day, I received a comment on my blog that was completely unrelated to the post. It happens all the time, and I usually use it as a judge of what my PageRank is - I could tell when it jumped recently because the flood of comment spam increased tremendously.

But this time, it was different. It was written from an actual person - valid email and all. And it linked to an actual company. So I decided to email the guy. I've removed identifiable pieces, but it's reprinted below.

I received this comment on my blog this morning:

Software re-use is what we do.
We are the porting and abstraction.

The link is to [His Company] and the email is yours. It's on my latest post, and at least for the time being, I'll leave it up there so you can go see it:

http://www.rosscode.com/blog/index.php?title=how_i_got_started_in_software_developmen&more=1&c=1&tb=1&pb=1

Did you leave this comment? This is a blog that I maintain and I don't appreciate the comment spam. If you want me to link to your company, then you need to give me a reason. I'm more than happy to look at what you have to offer and if I'm interested, then I'll post about it. But blatantly spamming my site is not going to work.

I will be removing the link in a few hours, and most likely banning the URL.

I've since removed the comment, but to his credit, I did get a response fairly quickly (edited to remove identifiable information).

I saw your comments about software re-use and I wanted to introduce you to [His Company]. [Marketing blurb]. Please check us out. I do apologize if you felt I was spamming you but as a software development professional I wanted to make you aware of a very good solution [More Marketing].

I don't think I was too harsh, considering that I have a do have a contact form and if his true intent was to let me know about his software, that would have been the way to do it. The only relation between his comment and my post was that I used the word "reuse" in my post talking about software I wrote in college, and it was meant as a joke! He obviously couldn't even be bothered to fully read the post, because that kind of comment is totally useless on a post about how I started in software development. The way he did it was, to me, a blatant attempt to get free advertising and link love. That's not fair to me, my readers or the paying advertisers who are part of The Lounge. If someone wants to advertise on my blog, then I'll be more than happy to point them in the right direction.

That's not to say that companies don't get free advertising on my blog. Just on the front page alone, I talk about and link to Michigan State, Deep Fried Bytes, KeePass, ISAPI rewrite, Filter.NET, Google Apps, Gmail, Outlook, Ninject, VHD Resizer, and Beyond Bullet Points. That doesn't even include links to many other blogs. Yes, I realize some of those aren't technically "for profit" but it's still promotion that they didn't request. Why was I willing to include a link to them? Because they're all things I am interested in and want to help them, even if it is just a link.

If the comment was even somewhat relevant to the conversation, that would be fine as well - for example, if someone had pointed me to StructureMap, that'd be great. It would have been relevant, even if I didn't include it originally. But comments unrelated to the content of the post just don't cut it.

Ironically, later that morning, I read this post from lifehack.org, which is all about the right way to get bloggers to promote your product. There's some really good advice about how to approach bloggers, but one thing it doesn't list is leaving random, unrelated comments. I'm seriously considering sending him that link so he doesn't make the same mistake again.

If this person would have contacted me directly and asked me to take a look at his product, I probably would have. I'd never heard of his company, but it looks like an interesting product. Too bad he spoiled it before I even knew anything about his product!

Category: Blogging

6 comments


 

How I Got Started In Software Development

posted on 06/05/08 at 10:52:36 pm by Joel Ross

Mike Eaton, a member of my twitter tribe, is trying to get to know his tweeps better. As part of that, he asks a few questions to get a better understanding of our background. I figured that rather than answer in his comments, I' post it here instead.

Anyway, his questions are in bold and my answers follow them.

How old were you when you started programming? I was in high school - my sophomore year. I wrote a text-based football simulation on the TI-85. I also wrote a few casino games that allowed you to take your winnings from game to game. I kept that program around for a long time - but eventually, the calculator got left in the basement for a while, and the last time I came across it, the batteries had been dead long enough that the memory was erased! About the only thing I remember about writing it was that there were lots of GOTO statements!

How did you get started in programming? When I started college, I intended to be an architect. Not a software architect, an actual architect - you know, the type that designed buildings. So I started out geared towards Civil / Mechanical Engineering. I'm not clear when it happened, but I suddenly realized I was heading towards Electrical Engineering, and I was OK with that. I'd taken a couple of intro to C/C++ classes, and it made sense, but I was still leaning towards engineering. Until I took Electromagnetic Fields and Waves in my Junior year. I just sat there thinking, "This doesn't make sense. Why would I want to know this?" but writing software seemed to make sense. From that point on, I switched focus from Electrical Engineering to Computer Science. As it turns out, if you combine the two degrees at MSU, you get Computer Engineering, which is the degree I ended up getting.

What was your first language? If you count the TI-85, it was BASIC. If not, then it was C when I hit college. I distinctly remember writing a program that simulated two trains going around in overlapping circles, and we had to handle stopping one train if the other one was already over the tracks. I've always been a model train fan, so if I ever get around to building a train setup in the basement, I can reuse that code to ensure my trains don't crash!

What was the first real program you wrote? What, a football simulator doesn't count? Fine. The first program I wrote that was actually used was a console app that would read a database and spit out a SQL file that you could use to rebuild the database, including schema and data. It started out as a way for us to script out the database for the main project I was working on (it was much quicker to write this simple utility than it was to manually create the scripts just a few times), but it ended up being a simple utility that was used on a few different projects. If you don't count developer utilities, then my first program was a system that allowed clients to build online forms, mostly used to create consumer loan applications. It ended up being used by 20-30 smaller banks to take consumer loan apps and checking/savings account apps online. That was originally released in 2000, and from what I've heard (I've since left the company), parts of it are still in use today.

What languages have you used since you started programming? I used C, C++, Lisp, and Basic in college. Then I used VB, ASP, and JavaScript. Once .NET came out, I switched back to the familiar syntax of C#, but could still use VB.NET if I had to. I've dabbled in PHP and Perl, but nothing serious - my PHP experience consists of what I've needed to manage this blog. Perl experience came because I had a boss who loved it and showed me how to do a few simple text manipulations, mainly parsing log files.

What was your first professional programming gig? I'd done simple things for a couple of jobs, such as the log parsing, but my first job where programming was part of the job description was with Crowe Chizek in Grand Rapids. I started there in late '99, and my first project there was the online application builder.

If you knew then what you know now, would you have started programming? Absolutely! I can't imagine doing anything else. I think it was on the second episode of Deep Fried Bytes that someone said, "I program 10 hours a day. I just happen to get paid for the first eight." Yeah, that pretty much describes my feelings.

If there is one thing you learned along the way that you would tell new developers, what would it be? Get involved in the development community. I don't do as much as I want to, but I do a ton more than I did when I first started out. That's because I had no idea what was out there. Once I learned what was out there, I jumped in (well, the best I could). It doesn't mean you have to be at every community event - it could be as simple as blogging or reading and interacting with blogs (or just twitter, for that matter), but make an effort to get to know the developers in your area - it'll pay off in the long run and you'll have a better support group to help you learn.

What's the most fun you've ever had ... programming? The best times I've had programming is in a team environment - and it get's better the later it gets. I remember one night that we were struggling to get a few things kicked out, and a group of 5 of us stayed until 1 or 2 to knock out a few of those things. We were all in a room together and we had about a 100 chicken wings brought in, some Mountain Dew and (eventually) beer. Music was blaring since we couldn't do that during the day, and no one was in a hurry to get out of there - we knew we needed to be there. Surprisingly, we were able to stay focused and really were productive, while still having fun. The interaction with the other team members seems to get more real when you're working close together and really cranking out the code.

I know originally that Mike asked for answers from his tweeps, but if you feel so inclined, go ahead and answer these questions for yourself. Either post them in the comments here, or better yet, post them on your own blog and just point me to it in the comments.

Category: Personal, Development

1 comment


 

Locking Down Web Servers

posted on 06/05/08 at 08:00:00 pm by Joel Ross

At about 2:00 PM on the Friday before Memorial Day Weekend, I talked to a client who was frantic over an issue where a part of their system appeared to be compromised. I spent the better part of the afternoon and evening with him trying to figure out what happened and how it can be prevented in the future.

We still don't know how it happened - it doesn't look like the server was hacked and looks more and more like it was a third party service that was actually compromised. But we couldn't be sure, so we went through and did a few things to lock it down a bit more. After we were done, he mentioned this should be part of our standard project plan. And he's right, it should. So I figured I would list out what we did, what we talked about doing on a longer term basis, and why.

This is by no means a comprehensive list, but these are some very simple things that you can do to ensure a bit more security for your applications. I think it's a good start, but I know there's parts I'm missing, so that's where I'll look to the comments to help fill this in.

Tags: |

Category: Consulting, Development, Software

Leave a comment


 

SlickEdit Tools

posted on 06/03/08 at 10:58:49 pm by Joel Ross

One of our new advertisers starting this month with The Lounge is SlickEdit, and as part of that, they offered us a chance to try out their SlickEdit Tools products. I love tools that'll help me be more productive, so I jumped at the chance. SlickEdit Tools is actually two products - Editing and Versioning. Both integrate with with Visual Studio, and since that's where I spend much of my time, that works for me.

I haven't had as much time writing code in the last month as I would like, so I've just been playing with it and haven't really had a chance to integrate it into my daily development habits. But one of the tools I did find very useful was the Auto Code Document Viewer, which takes your XML documentation and shows you what a help file would look like - as if you used NDoc or Sand Castle. It even allows you to save off the HTML pages for later use. This will make developing the NuSoft Framework easier, as I now have an easy way to see what our documentation looks like, without going through a long process to get it.

There's also a nice regular expression tool, with integration to RegExLib.com, which I could see being very helpful - I suck at writing regular expressions, but I understand their usefulness. Building them is a pain, and having an integrated tool to me is more useful than a separate application like The Regulator.

I do have one complaint so far about it, and I'll admit right now that it's nitpicky. They add a feature that allows you to count lines of code, which gives you a nice graph:

LOCReport

While useful, it's not something I want to check all the time. But I end up doing it because for 9 years now, when I want to go to the properties of something in the solution explorer, I do this from the keyboard:

Ctrl-Alt-L, Right-Click Key, Up Arrow, Enter

With the tools installed, here's the new right click menu:

 RightClick

As you can see, instead of "Properties", I get the line of code report. Like I said, it's minor, but it's a hard habit to break!

Tags: | |

Category: Software

Leave a comment


 

URL Rewriting Across App Domains

posted on 06/02/08 at 11:11:45 pm by Joel Ross

One of the clients I have been working with has an interesting situation where they want to use URL rewriting - but in a different way than I've seen in the past.

They've written an application for their clients, which is then used by their clients' customers. They have 100's of clients, each who has potentially 1,000s of users. As we talked about what the requirements were for the URL rewriting, we came up with two main ones:

  1. They should be able to have clients running different versions of the software on the same web server  They typically have three versions at any given time: Next, Current, and Past.
  2. Each client should have a consistent, non-changing URL. (for example, http://www.mysite.com/Client1)

The obvious solution is to create a virtual directory for each client and put the correct version of the software in each directory. Deployment can be easily automated, and you should be good to go, right? Well, not quite. With 100s of clients on the same server, you end up running 100's of app domains at the same time. That tends to tax your server just a bit. And by tax, I mean grind to a halt!

So we came up with an idea that we thought would work. The basic idea was to create a virtual directory for each version in production. Then in the root folder, you'd have a distributor application. It would look at the incoming request, grab the client ID, look up the client ID in a database to determine which version they were currently using, and then rewrite the URL to the correct version. As long as your application was aware of the way it has to build URLs, this would work well.

Or at least it sounded good in theory. In practice, it didn't work. As it turns out, you can't rewrite URLs across app domains. Or more specifically, you can't write to another app domain unless you have the DLLs you are writing to referenced in your application. That's a problem because we'd have to have references to three different versions of the same application. There would be namespace conflicts that would be tough to overcome. Potentially strong naming could help the situation, but it's not an ideal solution, and something we didn't really look into that much.

Eventually, we settled on an ISAPI filter that sits in front of the whole process and basically does the same thing that our distributor application was supposed to do. We couldn't use recommended filter - ISAPI rewrite - because our rewrites aren't static, and updating them every time a client moved versions would be a major hassle. We ended up using a managed ISAPI filter (Filter.NET). Because it's sitting in front of the app domains, it can handle the rewriting. It's a bit tougher to manage because it's an ISAPI filter, but it does give the flexibility they need, and the rewrites are written in managed code.

Ideally, I think we'd like to look at what IIS 7 has to offer and find a simple solution to our distributor problem, but I can't say whether that's there or not. I haven't looked at IIS 7 enough yet, and their servers aren't running Windows 2008 anyway (obviously). In the mean time, we want to make sure we're doing it the best way. Frankly, other than writing a pure C++ ISAPI filter (which would be much harder to manage, I think), I'm not sure I see any other valid solutions. I'm sure I'm missing something, so if you know what it is, please leave a comment!

Tags: | |

Category: Consulting, Development, Software, C#

Leave a comment


 

Tasks, Gmail, IMAP, and Outlook

posted on 06/01/08 at 11:38:58 pm by Joel Ross

My biggest frustration since moving all of my email to Google Apps has been around how Google's labels don't really translate to Outlook folders. For the most part, it's not an issue, but for certain things, it is. Tasks is one of those things.

In Gmail, a single message can have multiple labels. In Outlook, that translates to multiple copies of the same message in different folders. I don't typically label my messages with more than one label, but just by default, all messages get labeled "All Mail", and anything starred (or flagged in Outlook) gets labeled as "Starred" in Gmail. Those translate to folders in Outlook. As a result, whenever you flag a message, it shows in your tasks pane three times. That gets really, really annoying after a while and I eventually started ignoring my tasks altogether.

Well, the How-To Geek has a solution. Unfortunately, I couldn't use it as is, because I have other email accounts that I use besides the Gmail IMAP ones, so I had other folders I wanted to include. Instead of including the All Mail folder, I excluded it, as well as excluding "Starred". But that didn't work, and I had to modify the SQL directly - by default, any criteria you add is Or'd together, and I wanted it to be And'd, so I changed it.

Now when I flag a message, it shows up once and only once in my task list. Maybe I'll actually start using it again. Outlook is NOT the best at task management, but that's a whole separate discussion!

Category: Personal, Software

2 comments


 

Fluent Interfaces And Readability

posted on 05/29/08 at 10:52:45 pm by Joel Ross

I've heard people throwing the term "Fluent Interface" around, and, until recently, I had no idea what it meant - and more importantly, why I should care.

But then I started using one. At first, I didn't know I was using a fluent interface until I saw an example of a different one, and thought, "That's what I'm using!" I didn't even fully understand it at that point, but it definitely made the code a lot easier to follow.

So what was I using? Ninject, of course! For those who don't know, Ninject is a dependency injection framework, and it uses fluent interfaces for it's binding syntax. Here's an example of how you can bind an implementation to an interface to be used for a particular type:

Bind<IMessageLogger>().To<ConsoleLogger>().For<ConsoleService>();

In a typical implementation, the same thing is accomplished through a series of separate statements where you have to take into account the return types so you can deal with another call later on. Method names are typically longer because they're meant to be used in a stand alone fashion. By doing it this way, your method names tend to be shorter, but looking at that one line, it's pretty easy to see what's going on: I want to use ConsoleLogger whenever ConsoleService requests IMessageLogger.

So how do you create a fluent interface? It's pretty simple, really. I'll use orders and order lines as a simple example (even though Scott Hanselman is tired of Northwind!) I want to be able to write code like this:

order.AddLine("CPU", 2).AddLine("1GbRam", 4).SetTax("49456");

To accomplish that, we'd have an Order class that looks something like this:

   1:  public class Order
   2:  {
   3:     List<OrderLine> OrderLines { get; set; }
   4:   
   5:     public Order AddLine(string lineId, int quantity)
   6:     {
   7:        this.OrderLines.Add(new OrderLine(lineId, quantity));
   8:        return this;
   9:     }
  10:   
  11:     public Order SetTax(string zipCode)
  12:     {
  13:        // Calculate Tax based on Zip Code
  14:        return this;
  15:     }
  16:  }

The key is the return type. In this case, the two methods return Orders, so returning "this" is what we want - this allows you to chain your method calls together. You can also change the return type. This allows you (as the interface creator) to have control over what the next action can be.

Right now, I'm having fun using fluent interfaces. Eventually, I'll start to feel comfortable enough to start incorporating this into my own libraries. For now, I think I need to understand where it makes sense to use this a bit more first.

Tags: |

Category: Development, C#

8 comments


 

VHD Resizer To The Rescue

posted on 05/27/08 at 08:00:36 pm by Joel Ross

I use Virtual PC for all of my development. I have a VHD for each client, and this has saved me several times in the past. First, if my laptop ever crashes, I still have my VHDs. That means I just need an OS and Virtual PC, and I'm back up and running. Second, if clients use incompatible software, I'm safe. This happens quite often actually.

Anyway, a couple of my client VHDs have reached their size limit. My base VHD was built against Virtual PC 2004, and the drive limit was 16 GB. With Visual Studio 2005 and 2008 and SQL Server on it, some of them are running out of space.

I searched around a bit, and eventually found VHD Resizer. This allows you to take a VHD file, and change the size. You can also change it from a dynamic disk to a fixed size disk, or vise versa. It was a life saver for me, and allows me to continue using my VHDs without having to rebuild completely.

Tags: | |

Category: Development, Software

Leave a comment


 

Grand Rapids Tech Lunch

posted on 05/22/08 at 12:04:45 am by Joel Ross

Chris Woodruff, a co-worker at RCM, recently tweeted about an idea he had - getting people together for a tech lunch a couple of times a month. People immediately showed interest, and just a day later, the first Grand Rapids TechLunch was planned.

It's going to be at Bulls Head Tavern in downtown Grand Rapids on June 2nd from 12:00-1:30. There's space for 20, but if we get more, then we can move upstairs apparently. There's also free wifi, so that's a bonus as well.

Anyway, this will be an ongoing thing. Chris has a Facebook group set up to keep us up to date, and is working on getting a website set up. The group says it'll meet every two weeks, but after talking to him, I think it's only going to be the first Monday of the month, unless it's a holiday. Then it'll be the second. If interest really gets going, then it'll move to twice a month.

Anyway, if you're in the Grand Rapids area, come on out on June 2nd. And if you plan to attend, leave a comment!

Tags:

Category: Consulting, Development

3 comments


 

Beyond Bullet Points

posted on 05/15/08 at 11:36:42 pm by Joel Ross

A while back, I read Beyond Bullet Points, a book about putting together presentations with Power Point, but without using bullet points, or in essence, not making boring presentations. There's a lot of ideas that I really, really like about their approach. I've never been one to put tons of text on my slides anyway, so the approach wasn't exactly unfamiliar. It does require a change in how you think as your putting together your slides. I don't think I would necessarily go through the whole process of writing out everything I planned to say in my presentation as the book suggests, but I do like the idea of using graphics in place of boring text.

As a result of reading the book and hearing about other's experiences going beyond bullet points in their own presentations, I decided to do the same with mine. I had an existing presentation that I decided to rework. It already had a video incorporated into one of my slides, so I was on my way. My talk is about 30 minutes (then another 30 minutes of demos), and I have ten slides, with three not really counting - an intro slide, a demo slide and a resources slide (Yes, I could have done better on those, I'm sure). The other seven slides all had their original text replaced with a just a headline and a picture.

Here's a couple of before and after examples to give you an idea of the changes. This is from my presentation at the West Michigan Day of .NET this past weekend.

First, my continuous integration tools slide.

CIToolsOld CIToolsNew
Before After

Next, my CI tasks slide. I think this one is my favorite.

CITasksOld CITasksNew
Before After

As you can see, the after ones look a lot cleaner. It also has the added benefit that your audience doesn't spend the first 30 seconds reading your slide instead of listening to you explain what you want them to know.

Oh - while I was sitting in the speaker's lounge, someone mentioned that you can't do a presentation without a picture of a kitten in your slide deck. I'd never heard that before, but luckily, I had that covered as well!

CIHeadachesNew

I haven't received the feedback from the presentation yet, but the feedback I sought beforehand was pretty much unanimous that the new approach was better than the old one. To be honest, the new way takes a lot more prep - you need to know your material front and back because your slides don't give you nearly the hints that the old method does. Of course, I still cheated and had my speaker notes there for me to fall back on.

If you've read the book, you might be thinking that I missed the whole point of the book - to create your presentation "Hollywood-style" and treat it like a screen play. That's partially true. I got that from the book, but this was an existing presentation that I'd done a couple of times in the past and had it be successful. I didn't want to rework the whole presentation - I just wanted to tweak it a bit. Once I decide on a topic for another presentation, I'll go through the whole process then. For now, this was good enough!

Tags: | |

Category: Personal

Leave a comment


 

West Michigan Day of .NET '08

posted on 05/12/08 at 12:40:12 am by Joel Ross

On Saturday, I attended the West Michigan Day of .NET event, and had a great time - for the little bit I could actually be there. Unfortunately, I had to leave around lunch time, so I couldn't stick around as long as I would have liked.

Anyway, I arrived there early so I could be sure I was prepared for my presentation - I was second on the schedule. First, I grabbed breakfast, said hi to Jeff Tucker, Matt Davis and Seth Longcore (none of which have blogs - yet!), and headed to the speaker's lounge where I met Jay Wren and Dan Rigsby. I ended up skipping out on the first session so I could get in one last dry run before I was to go on. That didn't happen, since Mike Eaton, Dan Hounshell and Dave Redding walked in. Later, The Quick Solutions guys came in - Steven Harman, Tim Wingfield and James Bender. So yeah, no prep, but it was great meeting a bunch of people that I've interacted with online over the past 6 months (mostly via Twitter, the new conference back channel).

Chris Woodruff, who helped organized the event, introduced me to Patrick Foley (that's his twitter link. His blog seems pretty quiet). Despite being a Dallas Stars fan, he's a pretty decent guy and, as it turns out, has been working with a co-worker of mine on another project! Someplace in there (it's a blur), I met Jeff McWherter as well.

By then, it was time to head off to my session. I was up after Joe Wirtley, so I got a chance to say hi to him as he was unhooking his computer and I was hooking up mine. I had a slight technical issue getting the right resolution on the projector, but luckily I was able to work around it before I started. The session went fairly well. I would guess I had about 20-25 people in the session and had quite a few good questions. I was up against Josh Holmes and his building rich Internet applications session, which was disappointing, since I wanted to see that one!

After I finished up in my room, I headed over to Mike Eaton's Silverlight session to show support (read: tweet one liners from the back of the room). The room was packed, and only after I found a spot did I realize I was sitting next to Chris Broland, someone I've been following on twitter for a while. And when I say I realized who it was, I mean he told me who he was! Mike's session was pretty good - good content and good style. I've got a few pointers for him, but overall, he did a great job (especially considering he was partying all night before the event!).

After that, I pretty much had to leave. But not before I caught up with Dean Weber (no blog, Dean?) and had a nice conversation with him. After that, I headed back to the speaker's lounge to pack up. There were lots of tweeps in there that I hadn't yet met, but didn't have the time to do much more than pack up, so I missed a chance to introduce myself and say hi, which was a bit disappointing.

On the way out to the car, Wally McClure was grabbing something from his car, so I said hi, and I got a chance to meet him. We had a good conversation. Wally has a very distinct voice, which I'd become accustomed to through his podcast. I think I spent most of the short conversation thinking about how nice it was to put an actual person to the voice that I've heard on his podcast for a while now.

Then I got in my car and headed off. It was a great event, and I'm sure there's someone that I met that I didn't mention here, and if that's so, it's not on purpose. It was a whirlwind morning for me, and it's late after a very, very busy weekend!

Category: Personal

1 comment


 

Continuous Integration at West Michigan Day of .NET

posted on 05/11/08 at 11:13:32 pm by Joel Ross

This past Saturday, I gave a presentation on continuous integration at the West Michigan Day of .NET, and as promised, I'm posting my materials for anyone who wants them. Even for those who didn't attend, I think that simply by dropping your code into this process and modifying a few settings, you could easily have a build process ready to go quickly.

CI - What, Why & How (18.6 MB zip)

For those who were at the presentation, this is the contents of my C:\Build folder (the one that would be on the build server). I've removed all of the .svn folders. It also has my presentation slides, which don't have much content, but there are some notes in there. This was my first attempt at a more "Beyond Bullet Points" type of presentation, so hopefully it worked out.

Here's are the links to the tools I talked about, as well as the ones on the last slide:

Note that not all of these tools are free. NCover requires a license, and Simian is only free for free or open source software.

For everyone who attended, thanks for allowing me to present on something I am passionate about, and hopefully there's something that will benefit you on your future projects.

Tags: Continuous Integration | CruiseControl.NET | NUnit | NAnt | NCover

Category: Personal, Development

Leave a comment


 

Decorating Your Domain Entities

posted on 05/07/08 at 11:47:40 pm by Joel Ross

I don't have a specific link for this one, but I remember a conversation I had (on Twitter of course!) with Nate Kohari, author of Ninject, and Justin Etheredge about the attribute requirements specified by Inversion of Control containers on domain entities. Ninject, for example, requires attributes on properties to do property injection. During the conversation, I stated that I prefer to keep my domain entities clean, and not have them decorated with attributes. And Ninject supports that, so that's how I was using it.

But as I thought about it, I realized I was being hypocritical. Here's a sample property generated from the NuSoft Framework.

   1:  [DatabaseColumn()]
   2:  [TypeConverter(typeof(MinToEmptyTypeConverter))]
   3:  [DataObjectField(true, false, false)]
   4:  public string Username
   5:  {
   6:     [DebuggerStepThrough()]
   7:     get { return this._username; }
   8:     set { this._username = value; }
   9:  }

One property has four attributes!

Now the question is, which is the Right Way to do things? Are you OK with attributes in your domain entities, or would you rather have them be pure? Does it matter the direction of the attribute's intent? I.e., is it more acceptable to have an attribute for the data layer (which is underneath the domain layer) than to have an attribute for an IoC container (which sits on top of the domain layer)? Or vise versa?

And yes, I realize there isn't a Right Way that fits all cases. Anyway, I'm not sure where I stand now. I thought I liked clean entities, but I also see value in having the attributes as well.

Tags: | |

Category: Development, C#

2 comments


 

Validation In The NuSoft Framework

posted on 04/23/08 at 12:50:36 am by Joel Ross

One of the new features of the NuSoft Framework that we added for version 3 is validation. We went back and forth on how we wanted to implement it - at one point we even had a third party validation framework integrated into our project. We eventually decided against that, backing out those changes. We didn't want to distribute a third party DLL with our source. At the time, I was against the decision, but have since come around and think that what we've built has the functionality that we need. Note that I'm not saying necessarily that I think we should be against working with third party libraries - just that we won't include them with our source. We might provide the hooks to use them easily, but we won't include it by default.

Anyway, back to validation. We've include two types of validations out of the box - required fields and maximum length (for string fields). We also provide the hooks so you can include your own custom validations. It's much easier to understand with a code sample. Here's a check to see if a customer is valid.

   1:  if(this.Customer.IsValid)
   2:  {
   3:      this.Customer.Save();
   4:  }
   5:  else
   6:  {
   7:      foreach (ValidationError error in this.Customer.GetValidationErrors())
   8:      {
   9:          ErrorMessages.Text += error.ErrorMessage + "<br />";
  10:      }
  11:  }

We've added a property to all entities - IsValid - to determine if an entity is valid. If it is, then you can go ahead and save the customer. If not, then you can get at the errors and display them. Note that calling Save() without first checking IsValid when the entity is not valid will throw a validation exception.

Anyway, that's the very basics of validation. You can also validate just a particular property:

   1:  List<ValidationError> errors = 
   2:      this.Customer.GetValidationErrorsByProperty(Customer.CustomerProperties.ContactName);

As you can see, we've added constants for each property as a subclass to each entity. It's not perfect, but it does allow for a little bit of security to avoid "magic strings". The above call will validate just the "ContactName" property. By default, it will check to see if the field is nullable and if so, ensure that the current value isn't null. If the field is a string, it will also verify that the length does not exceed what the database can handle.

These methods are in EntityBase, so if you want to add custom validations, you can override the methods in the entity class - for example, in the Customer class, if I wanted to check that "ContactName" did not start with "Z", I can override the above method and add my validations:

   1:  public override List<ValidationError> GetValidationErrorsByProperty(string propertyName)
   2:  {
   3:      List<ValidationError> errors = new List<ValidationError>();
   4:      if(propertyName == CustomerProperties.ContactName)
   5:      {
   6:          if(ContactName.StartsWith("Z"))
   7:          {
   8:              errors.Add(new ValidationError("Contact Name can't start with 'Z'", this, propertyName));
   9:          }
  10:      }
  11:      errors.AddRange(base.GetValidationErrorsByProperty(propertyName));
  12:      return errors;
  13:  }

You can also do validation by groups. We have a class called ValidationGroup that holds the built-in validation groups: Length and Required. You can add custom ones to this class if you want as well.

The last main area I wanted to touch on with respect to validation is the events that we fire. We've added four events.

I listed them out in that order on purpose. When you call GetValidationErrors() (or check IsValid), the EntityValidating event will fire. Then, for each property validated, the PropertyValidating and PropertyValidated events will fire. Finally, the EntityValidated event fires. As is customary in the framework. the "ing" events have cancel abilities, so you can cancel validation. Obviously, canceling during a Save won't make the database accept nulls where it shouldn't, so you'd still get a Sql exception instead of a validation exception. The event args for these events contains the entity being validated and the current SqlHelper (if available), just like the standard EntityEventArgs. In addition to those, it also adds the property being validated, and the validation group being validated - if those are available.

So that's validation in a nutshell. I think we've made it pretty flexible, but I'm also realistic about it's limitations in it's current form. The one glaring issue to me is the fact that you can't validate a new value before you actually apply it to the entity. One thing I'd like to see is a way to test a value - maybe an overload on GetValidationErrorsByProperty that takes the new value - I haven't thought through the best way to do it yet, so I'm just speculating. But that seems like a decent way to do it without having to set the property on the entity to do the check.

This was actually one of the advantages of having a third party library - it gave us this ability. Not only that, but it would produce client side custom validators where it could - validating length, required fields, etc. Of course, it's been a very conscious decision to keep the framework UI agnostic, so producing ASP.NET specific validation controls isn't really something we want to do. We have the pieces to expose some of this, but right now, it would be a manual process and not necessarily intuitive. Maybe I'll follow this up with an example of you can do that.

For those who have used other validation frameworks, what features are we missing? How would you have done things differently? We're (in my opinion) still early in our implementation - it works and is extensible, but I know there's room for improvement. I just need someone smarter than me to help point me in the right direction!

Category: Development, C#, RCM Technologies

Leave a comment


 

NuSoft Solutions Acquired By RCM Technologies

posted on 04/21/08 at 11:21:12 pm by Joel Ross

It's old news now, but back in March, we were informed that RCM Technologies had acquired NuSoft Solutions. Here's the official press release.

For those who didn't know, I work at NuSoft Solutions (specifically the Kinetic IG group). And now, I work for RCM Technologies - still in the Kinetic IG group, as RCM doesn't plan to change much of what we do day to day. RCM is a publicly traded company, so this will be the first time I work for a public company. I'm not sure how it'll be different, if at all.

This is the second acquisition I've been through - I was with Sagestone when we were acquired by NuSoft. That transition worked out very well for me, so I'm hoping for more of the same this time around. Only time will tell.

Category: Consulting, Personal, RCM Technologies

2 comments


 

Speaking at the West Michigan Day of .NET

posted on 04/21/08 at 10:19:47 pm by Joel Ross

For the second year in a row, I will be speaking at the West Michigan Day of .NET on May 10th, 2008. I'll be doing a presentation on continuous integration:

The next release is looming in the distance, and you’re responsible for integrating the changes for all of the developers on the team. Last time, it took all day just to get it to compile. There’s got to be a better way! In this day and age of Agile software development, release cycles are getting shorter and shorter. As the build cycle gets squished, it’s imperative that a team doesn’t waste days at a time creating a build. Using Continuous Integration, development teams can “feel the pulse” of their project and be sure that builds aren’t a major headache. In this session, we’ll look at how a team can use continuous integration to enable quicker and easier builds, garner faster end user feedback, perform automated testing, and make deployments faster. Then we’ll dig into some of the common tools used to make continuous integration possible, followed by a demonstration of creating a simple, extendable build process.

Right now, I'm scheduled to go on at 9:45 that morning, but there's always a possibility that could change.

I'm really looking forward to this event - not so much my session (I've already seen it!), but all of the other great sessions and speakers that are going to be there. Just as an example, I'm up against Josh Holmes and Jay Wren, among others. I'll be there for at least part of the day and I'm looking forward to meeting a few people that I've interacted with on Twitter who are going to be there.

Category: Personal

Leave a comment


 

Screen-casting as a Support Tool

posted on 04/16/08 at 12:14:33 am by Joel Ross

Over the past week, I've been going back and forth with a third party vendor about some issues with their product. They have been unable to reproduce what we are seeing. We've gone back and forth giving them more detailed information, and they've been responsive, but they still can't reproduce what we're seeing.

As a developer, I can tell you it's just about impossible to fix a problem you can't reproduce locally.

So, we decided it would be best if they could see the issues we are seeing. Since we don't necessarily want to allow their support staff direct access to our installation (and their days are our nights), we decided a screen-cast would be in order.

TechSmith, who incidentally is located in Okemos, Michigan (near Lansing, where I grew up), offers a free product called Jing. I downloaded and installed it, and in five minutes, I had a nice two minute video that perfectly demonstrated the issues we were having. This should really clear things up, and given how simple this was, I can see doing this in the future as a good way to demonstrate (and show exactly how to reproduce) issues.

Category: General

Leave a comment


 

The NuSoft Framework (and me) on the CloudSocket Podcast

posted on 04/13/08 at 11:23:04 pm by Joel Ross

Chris Woodruff, a coworker of mine, recently started the CloudSocket Podcast. So far, he's published two episodes, and one of them is with me, talking about the NuSoft Framework.

It's a pretty short chat - about 18 minutes. It covers a bit of the history of the framework, a bit of the future direction, and a decent discussion of what the framework attempts to accomplish. If you listen to it, let me know what you think. Personally, I didn't think I touched on everything I should have or wanted to, but I've always been my harshest critic, so I'm curious what others think.

Category: Podcasting

2 comments


 

RossCode.com is Four Years Old

posted on 04/13/08 at 10:35:34 pm by Joel Ross

On April 13th, 2004, I finally had a blog set up that I felt comfortable with. I'd used blogspot, a couple of other generic blogging engines, and my family web site before that, but I finally decided that it was time to find a permanent home.

So I set this up. 1,114 posts later, I'm still loving having a forum to express my ideas, share my experiences, and develop a relationship with you - my readers.

It's been a great experience so far, and I'm looking forward to keeping this site going for a long time to come.

Category: Blogging

Leave a comment


 

RossCode.com Joins The Lounge

posted on 04/07/08 at 10:28:34 pm by Joel Ross

If you've visited RossCode.com (not in a news reader), you may have noticed that it's a bit cleaner - fewer ads, and only in the sidebar. Well, that's because I was recently accepted into the .NET Small Publishers Room in The Lounge, an ad network run by James Avery. The room is filled with high profile bloggers, such as Dave Donaldson, Steven Harman, Jim Holmes, Michael Eaton and others. From James' announcement:

Joel Ross is another great developer who I have gotten to know much better through twitter. I also have a chance of finishing in the top 3 of his bracket group if UNC makes it all the way.

Amazingly, I'm still in The Lounge, despite UNC losing to Kansas, which is what I was rooting for! Also, note the plug for twitter. That seems to be a theme lately.

And if you're reading this in a feed reader - business as usual. No ads in my feed.

Category: Blogging

3 comments


 

Announcing the NuSoft Framework 3.0

posted on 04/03/08 at 11:43:38 pm by Joel Ross

I'm very happy to announce that version 3.0 of the NuSoft Framework has been released and is now available. This release has been a long time coming, and we've had many, many internal debates about how we wanted to implement certain features, which resulted in large portions of implementations being added and subsequently removed.

But all of that is behind us now, and the release is done. So what did we add? Well, we pretty much stuck pretty close to the road map we laid out a while back. Here's the big ones:

We also fixed a few bugs that were brought to our attention, but those aren't a big deal. As you can tell, documentation is a bit lite right now, but we're working on it!

Category: Development, C#, RCM Technologies

Leave a comment


 

The Twitter Effect

posted on 03/31/08 at 11:09:10 pm by Joel Ross

If you've noticed a slowing of posts here, there's a reason for that: Twitter. Instead of posting short posts here about something I find interesting, I usually throw that on Twitter. Questions I need an answer to? Twitter is real time and so far, has brought great answers much faster than a blog post does - as an example, I posted a blog post the other night and was shocked to see a comment just seven minutes after the original post. On twitter, if you go seven minutes without a response, you're probably not going to get one - and most of the time, you've already gotten two or three responses.

So I've left my daily blogging habits behind and jumped into the micro-blogging scene whole heartedly. Where does that leave RossCode.com? Well, for the most part, my posts will have more answers than questions and will be longer and more in-depth then they have been. Of course, that means they take longer to write and more effort to create. Or simply put, I post less!

Does that mean I think this site is going to die over time? On the contrary - since I started using Twitter heavily, I feel like the blog has come alive. The number of comments has gone way up, and I feel much more connected than I ever have. Since I started this blog in 2004, I've had 390 comments. Since October of '07, I've had 140 comments - a full 35% of my comments coming in the last 6 months of a 4 year run. Right now, as I'm writing this, my home page has 10 posts on it, and there are 59 comments. So less than 0.1% of my posts (I'm well over 1,000) has 15% of the comments. And when I look at where the comments come from, most are either people I follow on Twitter or my responses to them.

To me, that's "The Twitter Effect." Since I started using Twitter, I feel I'm much more in touch with the community of developers in Michigan and the Midwest. I've made some great connections with people that I think will last for a long time, and the more and more I get into Twitter, the more great people I meet.

I remember going to Tech Ed in 2005. It was a real eye opening experience for me. I had read a lot of blogs, and it was the first time I had a chance to actually meet some of them in person. I met a few people there that I'm still friends with, and I quickly realized that conferences were more about who you met than the content available. Well, so far, Twitter has been that same thing - only magnified. I've interacted with some bloggers that I've respected for a long time on Twitter, and I've had my eyes opened to people I didn't know but probably should have.

Anyway, if you're not on Twitter, you should give it a try. Start by following me. Then look at who I follow and go from there. You'll probably start to recognize names. And if you do give it a go, let me know - I've started to be more and more picky about who I follow to avoid overload, but if you're a reader here, I definitely want to follow you!

Category: General, Personal

3 comments


 

Dependency Injection With A Framework

posted on 03/29/08 at 09:56:54 pm by Joel Ross

In a recent post, I laid out how I went about adding Dependency Injection to a particular class to give it flexibility and make it easier to maintain over time. At the end, I mentioned I'd never used a DI framework, mainly because I hadn't felt the need to do so. In the comments, Matt Blodgett mentioned that he'd like to see a simple example using a framework, and I agreed.

So last night, that's exactly what I did. I picked Castle Windsor, since that seemed to be a popular one, recommended by Michael Eaton and first on Scott Hanselman's list of DI frameworks.

All in all, it took about 30 minutes to get my existing code base to use it, and that included the time it took me to read the documentation to figure out what I'm doing. I'm obviously not an expert, and there's more I would like to learn, but I did get a basic example working.

For reference, here's our User class that we've been working with:

   1:  public class User
   2:  {
   3:     private IServiceAPI _service;
   4:     public IServiceAPI Service
   5:     {
   6:        get { return _service;}
   7:     }
   8:   
   9:     private string _userName;
  10:     public string UserName
  11:     {
  12:        get { return _userName; }
  13:     }
  14:   
  15:     public User(string userName, IServiceAPI service)
  16:     {
  17:        _userName = userName;
  18:        _service = service;
  19:     }
  20:   
  21:     public void SendMessageTo(string message)
  22:     {
  23:        service.SendMessage(String.Format("@{0} - {1}", this.UserName, message));
  24:     }
  25:  }

I realized after I posted my original post that I never showed what code to use this class would look like, but if you're not using a framework, it might look something like this:

   1:  IServiceAPI service = new TwitterAPI();
   2:  User user = new User("RossCode", service);

That's not really that complicated because we're just using one service, but if you start to get a few different services, you can see how complicated this could get.

To use Windsor, your code to instantiate the User class looks like this:

   1:  IWindsorContainer container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
   2:  IDictionary parameters = new HashTable();
   3:  parameters.Add("userName", "RossCode");
   4:  User user = container.Resolve<User>(paramters);

We use a dictionary to pass any non-injected parameters - our User class expects a username and an IServcieAPI implementation. We know the username, so we pass that in directly. We let the framework inject the IServiceAPI implementation.

There's actually more code to do it this way, but here's the key - this code doesn't change if I want to use a different IServiceAPI implementation. In the first example, I would have to add or change the code to get another IServiceAPI implementation. With the new way, the code doesn't change - Just the configuration. There's a decoupling advantage that I'll touch on later as well.

I did everything through configuration. It doesn't have to be, but that's how I did it. Let's take a look at the configuration file:

   1:  <configuration>
   2:    <configSections>
   3:      <section 
   4:        name="castle" 
   5:        type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" 
   6:      />
   7:    </configSections>
   8:    <castle>
   9:      <components>
  10:        <component 
  11:          id="business.user" 
  12:     type="Business.User, Business" 
  13:        />
  14:        <component 
  15:          id="service.twitter" 
  16:     service="Interfaces.IServiceAPI, Interfaces" 
  17:     type="Twitter.TwitterAPI, Twitter" 
  18:        />
  19:      </components>
  20:    </castle>
  21:  </configuration>

The first just sets up Castle as a valid configuration section. The key parts are in the <castle> section. I'm only using components - there's a lot more I could do here, but I don't need anything more than this. I've registered two components. The first (line 10) is the type I want to inject into, and the second (line 14) is the type I want to inject with. So, Business.User is the class that I want Windsor to construct for me. It'll look for a constructor, which in this case, expects a username, which we supplied, and an IServiceAPI-supported type. The second component has a service attribute, saying that it can be used when you need to find an IServiceAPI type. Then it specifies the concrete type to use - Twitter.TwitterAPI. So when Windsor tries to construct the first component (Business.User), it'll end up resolving the IServiceAPI parameter to Twitter.TwitterAPI. All of this happens with nothing more than some configuration settings!

Now let's say we want to swap out TwitterAPI for our ConsoleAPI class. Before, we'd have to modify the code to create a ConsoleAPI instance and pass it in. Now we just change our configuration to add a new service and specify which service to use:

   1:    <castle>
   2:      <components>
   3:        <component 
   4:          id="business.user" 
   5:         type="Business.User, Business" 
   6:        >
   7:          <parameters>
   8:            <service>${service.console}</service>
   9:         </parameters>
  10:        </component>
  11:        <component 
  12:          id="service.twitter" 
  13:         service="Interfaces.IServiceAPI, Interfaces" 
  14:          type="Twitter.TwitterAPI, Twitter" 
  15:        />
  16:        <component 
  17:          id="service.console" 
  18:          service="Interfaces.IServiceAPI, Interfaces" 
  19:         type="Console.ConsoleAPI, Console" 
  20:        />
  21:      </components>
  22:    </castle>

I've added a second implementation for the IServiceAPI service, and specified which implementation using the <parameters> element. the <service> element is what to pass in as the service argument in the Business.User constructor. In this case, I specified to use Console.ConsoleAPI, which would be another service that implements IServiceAPI. I can easily switch between the TwitterAPI and ConsoleAPI just by changing one config setting - no need to recompile. And I can add new IServiceAPI implementations in the future, add them as components, set it as the one to use for Business.User, and I'm ready to go - no code changes.

That last point brings me to another advantage I see: Decoupling. Before, my client code was tightly coupled to the TwitterAPI implementation. My User class wasn't, but the client using it was. Doing dependency injection by hand removed some coupling, but it couldn't remove as much as using a framework did. In the above scenario, I have five assemblies - Business, Twitter, Console, Interfaces, and Client (the only one not listed, but it would be the client code containing the Windsor code). Client doesn't need to have a reference to Console or Twitter, but can still use the classes inside of them. The assemblies just need to be dropped into the same folder as the executable. And if I ever add a Jaiku assembly, that just needs to be dropped in and configured, and suddenly my code can use it - without compilation.

One other thing to note, and then I'll wrap it up. My User class was unchanged. Some frameworks use attributes to specify where to inject to, but that would require changes to the User class. Windsor doesn't (or at least doesn't have to - I'm still learning!), so I'm free to use the class with a framework or I can do the DI by hand.

Overall, I'm really impressed with Castle Windsor, and I think I can see it's usefulness. To be completely honest, the recompilation (or more specifically, not having to recompile) isn't that big of a deal to me - I rarely am in a situation where I want to add functionality but recompiling the software is out of the question. But breaking a(nother) dependency is always a good thing, and being able to use configuration over code seems like a Good Thing to me.

Bottom line: I think I'll be looking at this a bit for future projects.

Category: Development, C#

12 comments


 

Using The Adapter Pattern

posted on 03/28/08 at 08:00:57 pm by Joel Ross

In my last post about Dependency Injection, I sort of just threw in a comment about using the Adapter Pattern to address a mismatch between existing classes and interfaces that those classes need to support. I didn't provide a link or any real explanation. It was late when I wrote it, so I didn't really think about it. After reading through it again today, it struck me that I should probably explain it and provide an example of that as well.

Actually, this is all just a ploy to write about as many design patterns as possible to prove to someone (who shall remain un-named for now) that patterns are worth it and useful!

The basic idea of an adapter is to allow a class (or set of classes) support an interface without modifying the class or the interface. There's a a couple of reasons you'd need to do this:

  1. Your set of classes all do the same type of thing (post to a micro-blogging service, for example), but with a different API, and you want to write code to treat them all the same.
  2. You have existing code that expects a certain interface. Your new class doesn't support that interface and it's not feasible to change that (for example, it's a third party library).

That all sounds good, but examples cement the idea for me. Let's take a look at an existing class (following on my example from the DI post).

   1:  public Class TwitterAPI
   2:  {
   3:     public void SendTweet(string message)
   4:     {
   5:        // Send tweet implementation
   6:     }
   7:  }

Now, let's look at the code that we want to use this. This code already is using DI and expects a class that supports the IServiceAPI interface.

   1:  public class User
   2:  {
   3:     private IServiceAPI _service;
   4:     public IServiceAPI Service
   5:     {
   6:        get { return _service;}
   7:     }
   8:   
   9:     private string _userName;
  10:     public string UserName
  11:     {
  12:        get { return _userName; }
  13:     }
  14:   
  15:     public User(string userName, IServiceAPI service)
  16:     {
  17:        _userName = userName;
  18:        _service = service;
  19:     }
  20:   
  21:     public void SendMessageTo(string message)
  22:     {
  23:        service.SendMessage(String.Format("@{0} - {1}", this.UserName, message));
  24:     }
  25:  }

Now, TwitterAPI doesn't support the IServiceAPI interface, so to make these two classes work together, we have a choice. We can modify the TwitterAPI class directly to support the IServiceAPI interface. But what if the TwitterAPI is a third party library or it's already in use in other places? Well, that's where the Adapter pattern comes in. We can wrap the TwitterAPI class with an adapter so it can be used in the User class. It'll look like this:

   1:  public class TwitterAPIAdapter : IServiceAPI
   2:  {
   3:     private TwitterAPI _twitter;
   4:     public TwitterAPI Twitter
   5:     {
   6:        get { return _twitter; }
   7:     }
   8:   
   9:     public TwitterAPIAdapter(TwitterAPI twitter)
  10:     {
  11:        _twitter = twitter;
  12:     }
  13:   
  14:     public void SendMessage(string message)
  15:     {
  16:        twitter.SendTweet(message);
  17:     }
  18:  }

Now we can pass in a TwitterAPIAdapter instance into User, and post to Twitter. The advantage of doing this is especially important for existing code bases. This allows these two disconnected pieces (User and TwitterAPI) to talk to each other but without modifying either class, meaning getting them to talk is less impactful to the overall system because neither original classes were changed.

This example is a simple one. But it does show the concept - to overcome the mismatch between the two classes and allow them to work together. In more complex situations, that may include pulling in information from other sources, pushing data to multiple locations, etc.

The adapter pattern is also a good way to encapsulate the functionality of a volatile piece of a system. For example, we have had issues with our HTML editor we use on Tourneytopia, and as a result, have changed it out a few times. The first time we did, it was painful because it's used in a few different places. The second time we changed it, it was easy because the first time, we created an adapter that sat between our application and the third party editor. Now we can swap editors out by just changing the internals of the adapter and our application never has to change.

Category: Development, C#

5 comments


 

Using Dependency Injection To Increase Flexibility

posted on 03/28/08 at 12:31:15 am by Joel Ross

Tonight, I was thinking about a side project I've been working on, and I realized that I had used Dependency Injection (DI). I'm pretty sure that DI is my favorite pattern, so I decided to share on twitter. Steve Wright responded:

I wonder what all the DI hubbub is about, do I even need it?  I keep asking, and I think it's time to figure it out

Seeing that, I figured I'd share how I used DI and what it accomplished for me. I'm sure Steve knows what DI is, but inspiration has to come from somewhere, right?

First, a little set up. I wrote some code that interacts with the Twitter API to send and receive messages. Without DI, it looked something like this:

   1:  public class User
   2:  {
   3:     private string _userName;
   4:     public string UserName
   5:     {
   6:        get { return _userName; }
   7:     }
   8:   
   9:     public User(string userName)
  10:     {
  11:        _userName = userName;
  12:     }
  13:   
  14:     public void SendMessageTo(string message)
  15:     {
  16:        TwitterAPI twitter = new TwitterAPI();
  17:        twitter.SendTweet(String.Format("@{0} - {1}", this.UserName, message));
  18:     }
  19:  }

This doesn't seem too bad at first glance. Yes, you could probably modify this a bit to make the TwitterAPI variable a class level variable and that would be a little better - you wouldn't have to instantiate it every time you wanted to send a message. But there's still a problem. What if you wanted to test this without spamming twitter? Or instead of twitter, you wanted to send messages to Pownce or Jaiku? Or your blog? How would you do that?

The issue is that the code above has a dependency on the TwitterAPI class, so you're pretty much stuck. What I've seen done (which makes me cringe) is to add switch statements where each case contains code to post to a different service. What happens when a new service comes out? Or you want to post to two services? You're stuck in a maintenance nightmare because this class has to change every time a new service comes out.

Luckily, dependency injection solves this problem. Instead of the User class having a dependency on TwitterAPI (or PownceAPI, JaikuAPI, etc.), it only depends on an interface, and the concrete implementation of that interface is injected into the class. In this case, the interface is pretty simple:

   1:  public interface IServiceAPI
   2:  {
   3:     void SendMessage(string message);
   4:  }

Then we can change our User class to use the interface, and have it injected into the instance through the constructor:

   1:  public class User
   2:  {
   3:     private IServiceAPI _service;
   4:     public IServiceAPI Service
   5:     {
   6:        get { return _service;}
   7:     }
   8:   
   9:     private string _userName;
  10:     public string UserName
  11:     {
  12:        get { return _userName; }
  13:     }
  14:   
  15:     public User(string userName, IServiceAPI service)
  16:     {
  17:        _userName = userName;
  18:        _service = service;
  19:     }
  20:   
  21:     public void SendMessageTo(string message)
  22:     {
  23:        service.SendMessage(String.Format("@{0} - {1}", this.UserName, message));
  24:     }
  25:  }

This effectively makes our User class service agnostic. I can now implement the IServiceAPI for Twitter, Jaiku, Pownce, an IM client, the console window - or any combination of those. Note that I changed the method name in the service from SendTweet to SendMessage. If you don't have control over your service implementations, then you can use the Adapter pattern to make that work.

The best part about using DI is that this User class can work with services that haven't even been thought of. As long as the service supports the IServiceAPI class (or an adapter can be written to simulate that support), then this class is already prepared to work with it.

I used this model so I could have all of the output to a console window instead of actually posting it, and I controlled which IServiceAPI instance to pass in via a config setting. In the actual implementation, I had a get method as well. The real one (against twitter) did XML requests, while my test one grabbed input from the console window. It made testing it very easy, and didn't require a lot of extra coding - especially using CodeRush to do some of the dirty work, like extracting interfaces, adding parameters to methods, etc.

I haven't used any formal DI frameworks, but that's mainly because I haven't come across a situation yet where I couldn't just code it up by hand. I've seen one in action, so I know they have their place, but I just haven't felt compelled to use one. Still, even with hand coding, Dependency Injection can really help write code that is flexible and resilient to changes in the future.

Category: Development, C#

15 comments


 

Going from the 80% to the 20%

posted on 03/25/08 at 10:18:35 pm by Joel Ross

Back in November, Jeff Atwood put together a post about the two types of developers: The 80% and the 20%. The 80% are the 9-5 type developers - they may be great at what they do, but they don't have an overwhelming passion for it - it's a job, and nothing more. Once they leave the confines of their office, they don't think about writing software until they return to the office the next morning.

The 20% are the people who are passionate about software development and are constantly looking for ways to better themselves. They read blogs. They speak at user groups and code camps. They're active in the community and are constantly pushing themselves to learn new things and find better ways to do what they're already doing.

In reality, it's probably more like 95% / 5%, but the definition of the groups remain the same. The real question isn't what group you're in - if you're reading this, you're most likely in the 20%, The real question is at what point do you (or did you) transition from the 80% to the 20%?

I know it's possible. I did it. I used to come to work at 8 and leave at 6 - not quite 9 to 5, but the bottom line was the same - when I left the office, I didn't think about work until I came in the next day. Nor did I think about software development. I learned what I had to learn to do my job, but nothing more. I was putting in my time and taking home a paycheck. I was good at what I did, but I didn't really do anything to push myself.

I don't remember exactly when it happened, but it did. I started finding blogs when I did searches. I started to wonder what this whole blogging thing was bout, and I felt like I needed one. So I started one, and I started following a few blogs. The key to switching from the 80% to the 20% was when "following a blog" went from a bookmark in IE to a subscription in Newsgator.

Eventually, I started doing other "20%-ish" things. I was writing software for fun. I started a side business specifically to fill in some of the gaps in my experience. I started speaking (although infrequently) publicly at .NET user groups. I used the best tools for my projects regardless of what the Microsoft corporate line is. I still feel like I'm barely in the 20%, but I'm there. I made the transition.

One of the questions that keeps popping up is, "How do we reach the 80% and teach them the best practices and the best software to use?" What we should be asking is, "How do we get more of the 80% into the 20% so they have the knowledge to learn that for themselves?"

Think about college. How much of what you learned in college applies to what you do right now? For me, it's next to none (of course, I wasn't in any of Professor Elder's classes!). So does that mean I don't think college is worthwhile? Absolutely not. Going to college was great for me. Not because of what I was learning, but because of the process I used to learn it. College taught me how to learn, which is more important to me than what I learned.

The 20% would be doing the community a disservice if at the end of the day, the best they did was teach other developers the best practices for software development today. How many people thing NUnit will be the unit testing framework of choice in five years? Some would say MbUnit has already usurped NUnit. The 20% would be much better off to show them the process to learn that for themselves.

I don't see a lot of discussion about people moving from one group to the other. But remember, some of the developers in the 80% are very smart. While some are content with where they're at, there is a good percentage that just haven't been exposed to the community and aren't even aware there are other options out there. Once they're aware, they may jump in with both feet and have lots to offer, and in the end, we'll all benefit.

I don't have the answers as to how to affect that transition process. I won't pretend to. But I know that the focus on Us vs. Them is the wrong approach. We need to start thinking about how we as a community can grow that community as a whole, and push that 20% to actually be 20% or even more.


I wrote this post last night. For the first time since I started writing here, I considered not posting it. Yes, I've thrown away posts before, but those were because they no longer applied. I think this one still applies, but I struggled with posting it. Obviously, I decided to go ahead. Also, just because I feel like I should disclose where this is coming from, there is a post by Dan Hounshell that prompted me to write about some of these thoughts. His post is worth a read, as are the comments.

Category: Consulting, Personal, Development

15 comments


 

1st Annual RossCode.com March Madness Pool Contest

posted on 03/16/08 at 11:17:19 pm by Joel Ross

For the first time, I'm actually going to step back and enjoy myself during the March Madness tournament this year, and host my own pool. I'm inviting readers of my blog (that's you!) and the people I know on Twitter. And anyone else I can think to invite.

There's no prize - just the pride of knowing that you picked the teams better than any of the other geeks! Of course, after you enter my pool, you'll be shown the option to add your pick to the main pool - where there is a prize - a $50 Best Buy gift card.

Oh yeah. If you're reading this and thinking, "There's no point in me entering. I don't know anything about basketball." - it doesn't matter. I've heard countless stories of people who won a pool by picking teams by uniform colors! So don't let that hold you back. Submit your picks now!

Category: Develomatic, Personal

Leave a comment


 

Protecting Yourself Through LLCs

posted on 03/10/08 at 10:07:04 pm by Joel Ross

As part of our recent transition from Tourney Logic to Develomatic, LLC, we've learned a few things about how to set up businesses. Some of them are worth sharing!

To start with, let me state that I'm not a lawyer, so if you're in this situation and wondering if this is the right solution for you, I claim no responsibility if you lose your house. Check with your own lawyers first. And remember, I'm in Michigan, so states may vary as well. And it's always possible I'm completely off my rocker to begin with!

Anyway, we recently learned the best way to organize our different entities. We have four major properties that we maintain - Tourney Logic, Tourneytopia, myPlayoffs.com, and Pay It Square. And I guess you could add Develomatic, LLC onto that as well, making five. While some relate, we track each separately and if the opportunity afforded itself, could sell them separately.

There's another side to this as well. In the event that something bad happened, we want the losses to stop at that entity. That is, if one of our entities got sued, we don't want that to have a negative impact on the other entities. Since we track them all independently, we know what kind of revenue or losses each one has.

So how can we accomplish that? Well, each entity is a separate LLC. So for our five entities, we have five LLCs. The LLC is a legal entity and will hold up in court to limit its liability to what it's made, so the losses wouldn't filter up to the rest of the entities and completely wipe them out.

Now, having heard this, my first reaction was "This is a ploy for the accountants get more money!" Five entities means five tax returns right? Well, as it turns out, no. The odd thing about LLCs is that they aren't technically recognized by the federal government - or at least not the IRS. No, to the IRS, the only thing that matters to them is if you have an EIN. If you have an EIN, you file a return. No EIN? No return. Now, that doesn't mean if you make money for an LLC that doesn't have an EIN, it's tax free. You still need at least one EIN. But for us, we can get an EIN for the "holding" LLC (Develomatic) and file a return under one EIN with all of the combined revenue of the separate entities.

Bottom line: Legal protection for each entity, but the tax simplicity of just one entity.

Category: General, Develomatic

6 comments


 

NuSoft Solutions Announced Kinetic IG

posted on 03/06/08 at 09:17:19 pm by Joel Ross

KineticIGFor a long time now, there's been talk inside of NuSoft Solutions (where I work) about bringing designers onboard. We use design services from a few local design firms on a good share of the public facing web applications we've developed, and we always thought it would be a good idea.

Well, late last year, we started doing just that. We also formed a new group within NuSoft called Kinetic IG (Yup - Silverlight - unless you don't have it installed, then it's flash), and that was publicly announced a couple of weeks ago at a nice event at Eve in The B.O.B. So far, things have been going a lot quicker than I thought they would - we're looking to add six designers in the near future.  We're getting a lot of interest in our services, as well as a bit of press coverage. By the way, one of the projects mentioned in those articles is one I'm still working on.

To be honest, I'm really excited about this change. From a day to day basis, it's not much different, but being able to work closely with designers is great. I'm looking forward to building a working relationship that can be much tighter than we get with outside firms. It'll be interesting to see where things go over the next year.

Category: RCM Technologies

Leave a comment


 

Getting My Attention Back

posted on 03/05/08 at 09:00:01 pm by Joel Ross

Attention equals time. It's really that simple. To give someone your attention, it takes time. If it doesn't take time, then you're not really giving them your full attention. And if you're not giving them your full attention, you're wasting everyone's time - yours and theirs.

That's been on my mind lately as I get involved in more and more things. IRC, Twitter, trying to keep up with writing blog posts, reading blogs, development, etc. And that doesn't even include the real important stuff - family. Some of those things aren't negotiable. Family and the job can't really get pushed away. Twitter is my current obsession. What I realized was that I was paying less and less attention to my RSS reader. Oh, I was "reading" a lot of posts, but if I was honest with myself, I didn't really read most of the posts. I scanned, and I scanned quickly. I was subscribed to 750 feeds after all!

So that's where I pushed back. I decided I wasn't getting anything out of reading blogs anymore, and that was disappointing, really. I used to get a ton out of reading blogs, but I wasn't picky about subscribing to new blogs - it was easy, so why not just keep adding?

Well, I found out why - it's too overwhelming. Since that time, I've cut my feeds down to 203 subscriptions. I'd like to get (and keep) that under 200, but I'm struggling to find the fat right now. And I'm taking the time to actually read what's important and interesting to me, which was the point, right?

So what did I cut? Mostly non-development blogs. Engadget made the cut, but a lot of other tech news sites were didn't, as well as blog media, blogs that don't update a lot, blogs that don't post about relevant topics, etc. Of the 203 left, not all of those are technical blogs - there's a few personal ones in there. But the technical ones are good and relevant.

Frankly, things are under control now, and I feel much less pressured to "keep up" since that's not as hard now, and when I do fall behind, it's not that hard to get caught up again.

Category: Blogging, Personal

2 comments


 

NuSoft Framework Background

posted on 03/04/08 at 08:37:50 pm by Joel Ross

Over the past few months, I've talked about the NuSoft Framework quite a bit, but after a twittersation (here, here, here, here, here, and here - Twitter needs threaded conversations!) with Matt Blodgett, I realized I've never really talked about what the motivation was for initially creating the framework. I've touched on it here and there, but nothing that I could point to and say "This is why we made the framework and why we use it over other options."

So let's start with the first - why did we even bother making the framework? There's plenty of other options out there, so why bother? Despite the fact that the framework became publicly available in the second half of 2007, it actually has it's roots at Sagestone back in 2003 or 2004. I started a new project, and it was against an existing database with 200+ tables. At the time, we debated typed datasets versus custom classes. The advantage that typed datasets provided was speed - creating them would be easy. You just imported your database and you were done, right? Yeah, except then you were stuck with the dataset's way of doing things.

So how could we justify using custom objects? Well, the only real way would be if we could quickly create those objects. One option was an O/R mapper, such as NHibernate. We considered a tool like that as others in the office were using them successfully. From my little experience with O/R mappers, it seemed that you still needed to create the objects and the mapping file. So really what you were saving was writing the SQL to persist your entities. Helpful, but that's still 200 classes to code up by hand, plus 200 mappings to create.

Better than all by hand, but not as efficient (from an up front development time) as datasets. As I started looking for easy ways to create the objects, I came across CodeSmith and a template that could create your hbm files. This was interesting, so I pulled down CodeSmith, which was free for generating code at the time. While my intent was to look into NHibernate, I started looking at the samples. Hmm. There was a sample to generate stored procedures for basic CRUD operations. There was a DAL template that worked with those stored procedures. And there was a simple model that got populated by the DAL. All were based on database tables. With a few modifications, that might work.

And so we tried it out. The time to generate all 200 classes was a little more than datasets would have been, but working with objects rather than datasets was much easier and more than made up for any speed advantage datasets had up front.

As I matured as a developer, I realized I wanted my entities to be much smarter than the model I'd been using. I slowly took those original templates and expanded them to be smart objects, tracking their own changes and ensuring they worked together to support transactions. I started looking into the CodeSmith API and figured out how to read relationships and started generating properties based on database relationships - Customer has a collection of Orders, Order has a Customer, etc.

At the same time, others inside of NuSoft (who, by that time, had acquired Sagestone) were doing something similar, but mostly by hand. And they had a base class that had some nice initialization methods for populating the entities. We eventually came together and over the course of a few lunch meetings and a lot of late nights, we came up with an early version of the framework. From there, we rolled it out internally. I gave presentations to both of our main offices and did a virtual meeting to get the word out. There, I laid out some of our core reasons for creating the framework (see, I'm finally getting to the point!).

Looking back at my rollout presentation, most of the reasons I listed were around being more efficient on our projects. From what we observed, there was a lot of variations from project to project, depending on who was in charge of the project. Our goal was to give every project the same basic framework to work against - that when you started a new project, you didn't have to worry about the technical details of saving or deleting objects, but you could focus on the domain problem - what the customer ultimately cares about. As a consulting company, our goal is to keep our bill rates up. One way to not do that is to charge customers to write CRUD code (that's Create, Read, Update, Delete - not cruddy code!). A side effect of this whole thing is that we're able to get new developers up to speed much quicker. First, they don't have to know the low level details to be productive, and second, as they explore the framework more and more, they learn the low level details - and since this is time-tested, they learn to do it correctly. And yes, I understand that "correct" is relative.

Anyway, if I boil our rollout to bullet points, here's the arguments:

Notice that none of this answers why to pick it over something else. When we started, SubSonic was still called ActionPack, and when I first looked at it, I didn't care for the fact that it exposed data readers to the UI, which I don't care for. .NetTiers was a lot more bloated than we needed in most cases. LINQ wasn't even on the radar. Just about everything we looked at didn't do what we wanted the way we wanted to do it. Given we were over half way there based on what we already had, it wasn't that hard of a decision to do it ourselves. Add to that having the flexibility to be able to add to it without relying on others or forking from the base, and it wasn't really that hard of a decision.

I realize this does nothing for those starting fresh and wondering why they should choose the NuSoft Framework over something else. SubSonic has come a long way (but still exposes readers to the UI), and LINQ looks promising, even with the problems I've seen with LINQ to SQL. But I think questioning why we even bothered with the framework is a bit naive. It's like asking why there are multiple IoC frameworks out there, and new ones keep coming out. Just because something similar is already there doesn't mean there's not room for a new entry into the field, and, as you can see, we had our reasons for doing it.

I guess it really comes down to preference. Does the NuSoft Framework do things the way you want them to be done, or not? Is it a closer fit than the other options? If so, then it might be for you. If not, well, it certainly doesn't hurt that there's competition out there.

While we don't have a huge external user base, the ones that do are very supportive of our efforts. Internally, I'm constantly hearing about new projects that are using the framework successfully. At a recent internal meeting with 40-50 developers in the room, someone asked how many had used the framework, and just about everyone raised their hands, which completely took me by surprise.

I think that's enough of a rant. If you've used the framework, please feel free to add your thoughts about why you chose it over something else in the comments. If you chose something else, let me know what we're missing. I'd love to get the feedback.

Actually, I forgot the number one reason we made the framework - whenever we met, we got free lunch. I never pass up free lunches!

Tags: | | |

Category: RCM Technologies

8 comments


 

Retrofitting Code for the Web

posted on 02/27/08 at 02:45:06 pm by Joel Ross

Yesterday, Scott Reynolds posed a question about a problem he'd run into while making a web interface for his current project. The essence of his issue is that they have a static class that stores the current user and database connection string, and having that be static in a web application is problematic - it gets overwritten whenever someone new logs into the web site. My guess is his class looks something similar to this:

   1:  public static class Data
   2:  {
   3:     private static string _userId;
   4:     public static string UserId
   5:     {
   6:        get { return _userId; }
   7:        set { _userId = value; }
   8:     }
   9:   
  10:     public static void SetUser(string userId)
  11:     {
  12:        UserId = userId;
  13:     }
  14:  }

He's got 200 classes that use this code, and doesn't want to modify all of those classes, so he asked if anyone had any input.

Well, we do something very similar to this on Tourneytopia, so I piped up, and provided him with a potential solution. I figured I'd share that here so anyone else who may run into this can see it as well.

The problem is not that the class is static. The problem is that the internal storage of the properties is static. Changing it slightly to allow for injection of a storage container will allow it to work with multiple users, while still allowing it to work without modification to the existing code base - the proposition of modifying 200 classes is pretty overwhelming! Here's the modified class:

   1:  public static class Data
   2:  {
   3:     private static string _userId;
   4:     public static string UserId
   5:     {
   6:        get 
   7:        {
   8:           if(_storage == null)
   9:           {
  10:              return _userId; 
  11:           } 
  12:           else 
  13:           {
  14:              return _storage.GetValue("UserId");
  15:           }
  16:        }
  17:        set 
  18:        { 
  19:           if(_storage == null)
  20:           {
  21:              _userId = value; 
  22:           }
  23:           else 
  24:           {
  25:              _storage.SetValue("UserId", value);
  26:           }
  27:        }
  28:     }
  29:   
  30:     public static void SetUser(string userId)
  31:     {
  32:        UserId = userId;
  33:     }
  34:   
  35:     private static IStorage _storage = null;
  36:     public static void SetExternalStorage(IStorage storage)
  37:     }
  38:        _storage = storage;
  39:     }
  40:  }

A few things to note about the update. First, it uses an interface (IStorage) to handle storage - as long as it's set. If it's not set, it defaults to the static fields it used previously - meaning the existing clients will continue working as they did in the past. New clients will call SetExternalStorage passing in an IStorage instance when the client loads (i.e., on initialization of the web site). I suppose you could have used an IoC framework to handle it, but that seemed like a bit of overkill to add that just for this.

The interface itself is pretty straight forward, and would reside in the same DLL as the static class above:

   1: