It’s difficult to break away from old traditions, but sometimes it pays to think a differently. NHibernate is an awesome example of what I am talking about. It gives a developer the flexibility of concentrating on writing code instead of having to synchronize the database with the data layer/code.

Currently, what I see happening quite often is the following.

  1. Specification document gets drawn up.
  2. Database is slapped together by the developer or DB “dude”.
  3. Developer starts working on the code, only to realize that a column is missing due to either poor planning or requirements changing, the developer spends time having to change/add a column/s and tracking down all the changes in the stored procedure and hopefully he/she has tracked all of them down, otherwise….

    15154

I have 2 words, Fluent NHibernate…

How to setup Fluent NHibernate

  1. Download Fluent NHibernate from http://fluentnhibernate.org/downloads
  2. Add references to the DLLs
  3. Create your first Entity
    public class Person
    {
    	public virtual int ID { get; private set; }
    	public virtual string Name { get; set; }
    	public virtual string Lastname { get; set; }
    }
    
    public class PersonMap : ClassMap<Person>
    {
    	public PersonMap()
    	{
    		Schema("dbo");
    		Table("Person");
    		Id(x => x.ID);
    		Map(x => x.Name);
    		Map(x => x.Lastname);
    	}
    }
  4. Setup Fluent NHibernate and this is where fluent really shines. No more having to deal with the pain of the XML configuration.
    public static class SessionFactory
    {
    	public static ISessionFactory CreateSessionFactory()
    	{
    		return Fluently.Configure()
    			.Database(MsSqlConfiguration.MsSql2005
    			.ConnectionString(
    				c => c.FromConnectionStringWithKey("AthenaConnectionString")))
    			.Mappings(
    				m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
    			.ExposeConfiguration(BuildSchema)
    			.BuildSessionFactory();
    	}
    
    	private static void BuildSchema(Configuration config)
    	{
    		new SchemaUpdate(config).Execute(true, true);
    	}
    }
    
  5. How to use Fluent NHibernate in a simple example
var sessionFactory = SessionFactory.CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
	using (var transaction = session.BeginTransaction())
	{
		Person person = new Person { Name = "Pieter", Lastname = "Germishuys" };
		session.SaveOrUpdate(person);
		transaction.Commit();
	}
}

3JDQDM2DSFR8

Isn’t symmetry nice? I always have some OCD when it comes to diagrams. So, it’s not surprise when you see this screenshot of the Linq2Sql Contextathena_dbml

Along with this, now we can go ahead and create Athena.DAL which contains the Linq2Sql context.

The solution isn’t that far long, so I won’t put up any code yet.

From this fantastic post on implementing the Repository pattern using Linq2SQL, we quickly put together some code that resembles the following

The Repository Interface

namespace Athena.DAL
{
	/// <summary>
	/// Repository Contract
	/// </summary>
	public interface IRepository<TRow, TEntity>
		where TRow : class
	{
		#region Find
		IList<TEntity> Find(Expression<Func<TRow, bool>> exp);
		TEntity FindSingle(Expression<Func<TRow, bool>> exp);
		#endregion

		#region Save
		void Save(TEntity entity);
		#endregion

		#region Delete
		void Delete(TEntity entity);
		#endregion
	}
}

Our Entry Model, which will describe an Entry fully

namespace Athena.DAL
{
	/// <summary>
	/// Entry Model
	/// </summary>
	public class EntryModel
	{
		public Entry Entry { get; set; }
		public List<Tag> Tags { get; set; }
		public List<Category> Categories { get; set; }
	}
}

and now for our not yet implemented EntryRepository

namespace Athena.DAL
{
	/// <summary>
	/// Entry Repository
	/// </summary>
	public class EntryRepository : IRepository<Entry, EntryModel>
	{
		#region Find
		/// <summary>
		/// Find
		/// </summary>
		/// <param name="exp"></param>
		/// <returns></returns>
		public IList<EntryModel> Find(System.Linq.Expressions.Expression<Func<Entry, bool>> exp)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Find Single
		/// </summary>
		/// <param name="exp"></param>
		/// <returns></returns>
		public EntryModel FindSingle(System.Linq.Expressions.Expression<Func<Entry, bool>> exp)
		{
			throw new NotImplementedException();
		}
		#endregion

		#region Save
		/// <summary>
		/// Save
		/// </summary>
		/// <param name="entity"></param>
		public void Save(EntryModel entityModel)
		{
			throw new NotImplementedException();
		}
		#endregion

		#region Delete
		/// <summary>
		/// Delete
		/// </summary>
		/// <param name="entity"></param>
		public void Delete(EntryModel entityModel)
		{
			throw new NotImplementedException();
		}

		#endregion
	}
}

So, here is a quick database design of Athena, the blogging engine that I am building as a pet project. Also, my girlfriend recently asked me if I wouldn’t code something for her, so there is some motivation behind it, other than the geek inside of me.athena

Next, we need to create a new ASP.NET MVC 2.0 Project and start working on the model.

This framework is not at all supposed to challenge or replace a blog engine but to merely be an effort from myself to showcase some of the fantastic and cool technologies out there.

I chose Athena because she is the Greek god of wisdom!

athena

I have already blogged about some of technologies that we are going to use, so tonight, we are just going to quickly put the framework together and then start playing.

Caching considerations
Donut hole caching from Phill Haack!
The Repository Pattern
This thread on StackOverflow

The Output cache is a clear winner for fast and effective caching, but like Mr. Haack has mentioned, only use it when it’s the right tool for the job. The Output Cache can give a great bit of flexibility with regards to where the output is stored.

The current locations for the Output Cache are the following
from http://support.microsoft.com/kb/323290

    • Any - This stores the output cache in the client's browser, on the proxy server (or any other server) that participates in the request, or on the server where the request is processed. By default, Any is selected.
    • Client - This stores output cache in the client's browser.
    • Downstream - This stores the output cache in any cache-capable devices (other than the origin server) that participate in the request.
    • Server - This stores the output cache on the Web server.
    • None - This turns off the output cache.

Models
I currently have about 10 tables which are all sitting inside of a Linq2SQL dbml, I then have a Context class that managed the Linq2SQL database context.

For instance, let’s say I want to get entries, the Context class will make sure that the Linq2Sql context is up and retrieve all the entries

The ViewModels
Every View has a “ViewModel” associated with it. Let me give you an example.
For a blog, where you would like to view an Entry, the Entry might contain a title, content, tags and some comments.

The View Model for the View Entry (View) would look something like this

public class EntryViewModel
{
	public Entry Entry { get; set; }
	public List<Comment> Comments { get; set; }
	public List<Tag> Tags { get; set; }
}

The Controllers
They perform pretty mondain tasks, such as begging the ViewModel for some data. i.e. I want to view entry "”Hello World”, go fetch the data for me. Which the ViewModel in turn requests from the Model.

The Views
They are pretty dumb alright, all they do is take the ViewModel they are given and display it the nicest way they can.

The technologies that I am using include the following

Data Layer
Linq2SQL

Logging
Log4NET

Client Technologies
ASP.NET MVC 2.0
JQuery
ValidationEngine (Because validation is a mess :))

Mocking Framework
MOQ

In January of 2006, Jeff wrote a post about why Code Reviews are important and I agree 100% that it's the only way to improve yourself as a developer.
He also pointed to Karl E. wiegers book titled - "Peer Reviews in Software".


It's all about sharing and caring about your code and the product you are building.

You might ask what you should check for in code reviews?

  • 1. Is it readable? Has the coding standards been maintained?
  • 2. Determine what the code is supposed to do.
  • 3. Determine what the code is currently doing and how it's doing it, is it doing it effeciently?
  • 4. Have a look at the individual modules. If an object is called Person, make sure that the object describes a person fully and completely and only maintain a "person's" responsibility. Ask questions like, should this person object be able to make updates to a database or should there be a DatabaseContext object that handles this by accepting a person as a parameter. databaseContext.UpdatePerson(Person person);

The most value comes from talking to the other developer and learning from them and they might just make you realize that there are things that you haven't thought of. Libraries that might have made your life easier, reduced the time that you spent on writing a section of code.

There are so many times that I see little gremlins hopping around in code and this is just me venting about it.

Naming Conventions

There have been numerous posts, articles and tweets about naming conventions and this is just my rant about this very topic.

Why use naming conventions?

The answer is pretty simple, chaos will ensue and little gremlins will run around your code, because no developer will be able to quickly glance at the code and understand what is happening because names like “Rdr” and “obj” (which, by the way is my favourite) just doesn’t describe what the variable is supposed to be used for. Furthermore, if you have no standard, you don’t know whether or not the variable is a parameter, member variable or property of the class.

Do you see what I’m getting at?

Naming convention reduces the time for a developer to look, understand and use the code. Naming conventions on MSDN

Consider the following lines of code

public class cPerson { private int iAge; private string sName; }
public class Person { private int age; private string name; }

You should be able to infer the type from the name of a member of a class. Age is an integer, it’s definitely not a double, nor is it a string.

You should not need to prepend the member with the first letter of the type. The type should be inferred. Instance naming This is where I just go absolutely mental. Take a look at the following code. Mixed up in a 400 line method where you have to first figure out what type the variable is because its name doesn’t describe it completely.

SqlConnection con = new SqlConnection();
SqlConnection northwindConnection = new SqlConnection();

Conclusion

I believe that it’s so important that as a developer, you should standardize your naming conventions as long as it’s readable, understandable and logical.