A buddy of mine asked for a copy of the database access strategy on my current project. We're not talking about repositories or data access layers or anything like that. We're talking about all the way down to where the call is actually made to the real database. So I give you...
or get both as code in DatabaseGateway.zip
I'm not going to walk you through the code here. You can do that at your own leisure if you want to. The interesting part of the gateway to me is its use. Most of the time, you'll find something like this in our code: _db.ExecuteQuery(Query.For(prepare, map)). "prepare" and "map" being delegates declared locally. In other places you'll see something like _db.ExecuteQuery(new MySelectSOHeaderQuery(salesOrderNumber)) where "MySelectSOHeaderQuery" is a private nested class that implements IQuery (or IResultQuery<SalesOrderHeaderDTO> in this case).
The main thing I wanted when I created this was to simplify data access down to the fact that we want to execute queries against the database. Since that's the way we say it, that's the way the code should read. Therefore, when you're reading our data access, you see (if you look at it just right) the statement, "database, execute this query".
If you look at the code, you'll notice there are three different types of queries: queries that just do things, queries that return things, and queries that should be audited. No matter the type, they're still just queries. That's why in the database gateway the three overloads are named the same - because we're still just executing a query against a database and that's the way the code should read.
Keep in mind the vast majority of our data access is done with nhibernate. There are a few left-over queries against our own database that still use this gateway (left over from before we started using NH). Most of the gateway's use comes from our interaction with other systems. You see, we still value connection string sharing as an acceptable SOA strategy ("we" doesn't include a few of "us" so please be easy).
Feel free to comment with any questions or thoughts about it. Enjoy!
Tags: .net, architecture
I've been asked a lot lately about why one would choose MVC over Web Forms. I'm not so sure about when one should, but I know my default choice is always going to be MVC.
Here are a couple of reasons why
Closer to the metal
With the lack of server controls and postback model, I find myself writing more raw HTML. I like that. Some people won't and that's fine by me. I do.
Forcing developers closer to the metal is forcing developers to realize what is actually happening. That has to be a good thing.
Forces a more user friendly design
You know how in web forms you can build an entire workflow in a single page using the postbacks? You know, selected index change event on a dropdown, lookup buttons, sorts, filters, wizard controls, tab controls, etc. All these things causing postbacks and firing events and the URL never changing. It's all happening in place due to the magic of web forms and viewstate.
Well, I find that doing anything like that in MVC is hard. And I love that! The result for me is that I end up rethinking my view. I find my putting myself in the shoes of the end user and concentrating more on how to allow them to accomplish the goal as simply as humanly possible. If I really do need richness or dynamic data to accomplish the task, I'm going to do it in an AJAXy way because that's easier than posting back and forth. For the end user, that's a very good thing!
In a nutshell, I tend to focus more on accomplishing goals and less on editing data when I build with MVC.
All the other goodness
Google MVC vs. Web Forms and you'll find a ton of other opinions. I agree with just about every reason you find that favors MVC :). They're all good and whatnot, but the above two are my favorites.
Tags: .net, asp.net, mvc, architecture
These extension methods are becoming a staple in every project of mine. I just wanted to archive them and put them in a place I could easily point to.
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Action<T> action)
source = source.ToArray();
foreach (var item in source) action(item);
public static IEnumerable<T> TryEach<T>(this IEnumerable<T> source, Action<T> action, Action<Exception, T> onError)
return source.Each(item => item.Try(action, onError));
public static void Try<T>(this T item, Action<T> action, Action<Exception, T> onError)
catch (Exception ex)
if (onError != null) onError(ex, item);
public static T As<T>(this object source)
public static T FindById<T>(this Control control, string id) where T : Control
public static string F(this string source, object arg0)
return string.Format(source, arg0);
public static string F(this string source, object arg0, object arg1)
return string.Format(source, arg0, arg1);
public static string F(this string source, object arg0, object arg1, object arg2)
return string.Format(source, arg0, arg1, arg2);
public static string F(this string source, params object args)
return string.Format(source, args);
I gave a presentation to our internal user group at work today (devloop). The topic of the day was "Getting Started with NHibernate". I'd say it went alright.. there was plenty of interest and several people wanted the code afterward. Good sign I suppose. However, I thought I did a crappy job.
- I didn't prepare hardly at all (though I was given very little notice)
- I felt chaotic and rushed the whole time (common result of poor prep)
- I did some things for the sake of time that I would never prescribe on a real project
- I did some things that added too much noise to the topic at hand (MVC, repository, and unit of work for starters)
So then, I don't think I'll share today's mayhem that resembled C#. Instead I took some time this evening to put together my first screencast. This presentation goes way back to basics and focuses on nothing but getting going with nhibernate, linq to nhibernate, and fluent nhibernate. No patterns. No best practices. Just the absolute basics on getting going from scratch.
The code from the screencast: 2009-10-14_NHDemo.zip
The screencast: 2009-10-14_nhibernate.wmv (this seems to have gotten deleted!)
And finally, in case you're wondering...
All in all I had fun putting it together. I am quite sure there are more efficient ways of going about it though :)
Tags: .net, nhibernate, linqtonhibernate, fluentnhibernate
I just wanted to post the code from last night's NWADNUG lightning round for those who asked.
A group of us were also talking about repositories at Jose's after the meeting. I wanted to remind of you this post where I showed the repository I use on one of my projects at work. It's another case where I'm not using an IoC container to manage the unit of work.
Feel free to fire away with any questions!
Tags: .net, nwadnug, linqtonhibernate, community