Toph - Early Architecture Decisions

by November 9, 2012 12:29 PM

In Another Gig Completes, I mentioned planning to start a new project to help track consulting gigs. Here I introduce you to:

Toph

Project codename named after Toph from the Avatar: The Last Airbender

As I mentioned before, this project is meant not only to help organize my consulting gigs, but also give me a public project and codebase I can point to. I also hope to use the project as blogging fodder. Speaking of which...

Early Architecture Decisions

I've spent the vast majority of my career joining existing projects. There is always that sense of "that's not the way I would have done it". Well, I finally get to do it my way! It was tempting to go crazy with it and implement everything cool I've been reading about recently - whether needed or not, I might add. In the end I decided to go with a pragmatic approach that is much more likely to be a useful example I can point to when talking to developers as I continue consulting.

Visual Studio Projects

I'm still a fan of and will continue to advocate onion architecture (some might say Hexagonal Architecture). One difference you'll find between Toph and what I normally do though, is the lack of an Infrastructure project.

There seems to be a theme going around the blogosphere that is advocating the removal of unnecessary abstractions and part of the theme has been the combining of projects. The idea is that it is perfectly possible to create an architecturally sound solution without using Visual Studio projects to enforce it. In case you're wondering how they "enforce" it, realize that Visual Studio projects won't allow circular references between two projects - whether by directly referencing each other, or indirectly (A - B - C - A would not compile). Therefore if you have a UI and a Core project with UI referencing Core, you couldn't reference UI from Core.  Thus, this usually prevents you from directly doing UI type actions from within Core since you couldn't touch the controllers or view models.

I'm almost always a fan of pragmatic programming. As it turns out, the Infrastructure project never proved that exciting for me as a standalone project. So I just created a namespace within UI called Infrastructure and dumped everything in there. You see, everything usually consider Infrastructure is generally only used during application startup anyway as I'm building up the inversion of control container.

However, I still very much like having my Core separate. It just feels right. So, I decide three projects are all we'll need in this solution

  • Toph (I decided there was no reason to call it Toph.Core)
  • Toph.UI
  • Toph.Tests

Even if I end up adding another project in the future for scheduled tasks (to be run on some application server somewhere), leaving Infrastructure under UI should still be fine. That's because I generally just invoke endpoints in the UI from those background tasks rather than directly dealing with the domain or application's database.

UI

New projects should always be started with the latest and greatest, right? I went with ASP.NET MVC 4 of course. Specifically, I started with the Internet Application project template.

Data Access

That template starts with using a local database and using Entity Framework as its ORM of choice. As expected if you know me, I changed that use SQL Server 2012 Express and NHibernate. To do that...

  1. Delete InitializeSimpleMembershipAttribute. This is the attribute added to AccountController that ensures the database exists and is initialized. There is only one line in there that is needed: WebSecurity.InitializeDatabaseConnection.  I moved that into Application_Start
  2. Delete UsersContext. This is the EF DbContext
  3. Move UserProfile from the Models directory into the domain and kill the EF attributes
  4. Add Fluent NHibernate
  5. Do all the normal NHibernate config and mapping stuff
  6. Change your connection string
  7. Create the database with the single UserProfile table
  8. Run the application

That should do the trick.

Other notables

The only other things I added to the project were Structuremap and my personal code library RobTennyson.Common.

I also stuck with restricting domain access to a Service Layer like I usually do. One difference I thought I'd toss into the mix this time is a bit of CQS goodness (not full blown CQRS, mind you). We'll see how this turns out as the project grows.

Grabbing a copy and playing

If you're interested in playing around with this, but sure you get the code specifically from this commit: 91a19e9f8b

I'll be moving on with the project of course, but at that exact point, the project is still basically just the default template - well, juiced up a bit, but basically still has nothing to do with the real project in it yet.

Happy coding

Tags: , , , ,

Database Gateway

by March 29, 2010 11:14 AM

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...

DatabaseGateway.cs
IQuery.cs
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: ,

What I like About ASP.NET MVC

by March 16, 2010 10:42 AM

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.

I meet too many developers who have no idea what the server controls they use actually end up as in the browser. That blows. Some don't even realize the server controls are not real HTML elements. Some don't notice the difference between server and client. I can't remember how many times a developer has asked me if they can call C# from HTML or if they can call javascript from the codebehind. I know the answer to both is "yes" in a round about funky way, but you know what I mean.

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: , , ,

Branching Strategy

by November 24, 2009 02:35 PM

Check out http://stackoverflow.com/questions/16142/what-do-branch-tag-and-trunk-really-mean for some good discussion about branching strategy.

This is in reply to a question about our branching strategy on my current project at work.

  • Main - similar to "trunk". Contains the latest and greatest code and is always ready to deploy to production.
  • Dev - similar to "branches". Any feature that will take more than one check-in to finish should be done in a branch. This is to facilitate the most important part of main – always ready to deploy. And of course, we check-in frequently as a good practice so branching is pretty important.
  • Prod - similar to "tags". Contains the code that is currently in production. If it's a web app, you only really need one branch in here unless you think you might actually roll back to a previous version. This branch is useful when you need to immediately fix a bug in production but aren't quite ready for main to be deployed. Just because main can technically be deployed, doesn't mean the business is ready for it. The reason you see so many versions in our prod folder is pure laziness. It needs to be cleaned up big time.

And for the other two questions:

When you branch, you need to remember to check in the code you just branched. The icon mentioned is TFS's way of telling you that you haven't checked in the branched code yet.

We get the version number from the version of our core library. Many projects will use a shared settings file or something to ensure all the libraries within a solution have the exact same version - much cooler than the way we do it :)

Hope that helps!

Tags: ,

Paul's Final Iteration

by October 11, 2009 05:16 PM

I was poking around in my data the other day doing a bit of housekeeping and ran across the recoding of Paul Clements' final presentation to devloop before leaving the company. I hated to see it hidden away on my HDD so I decided to chop it up and post it for all to enjoy!

Wise words from a wise man: Paul's Final Iteration

Enjoy!

Tags: , , ,