MVC – Books and source code!

by Mikael Henriksson 29. March 2009 17:42

MVC is not very hard to understand or grasp but the level of freedom it offers is pretty overwhelming! There are tons of great resources out there and stackoverflow offers some great answers even to the most difficult questions.

What I need is some books in the matter. I just love reading books. I know Scott Hanselman prefers to read code over books but me I really prefer the books before the code so that I can get a clear understanding what the framework is supposed to do FOR me. I have a bit of problem understanding a new framework from reading someone else’s code since whoever produced the code is bound to have hacked and slashed the way of the framework in a manner that suits him or her.

Fortunately there are some books coming out on the MVC framework during June-August and I ordered a few of them. Fredrik Normén wrote a blog post a few days ago about html being so 1990 and I totally agree but the step to Silverlight is going to take some time and MVC is a great way of doing .net until I go nuts while trying to learn something like Silverlight.

Anyway this is not supposed to be a post about what technology is the future I was supposed to post a few links where it is currently possible to to get on the way with MVC.

Let’s start with the useful free source code.

  • Nerd Dinner – Great tutorial, 189 pages PDF and source code. Think this is part of a book or something and worth looking in to. Code is small, simple and well organized and just the type of thing needed to get going. Cheers for the gift Scott!!
  • Code Camp Server – Some very advanced code here. Maybe not for the beginner. It’s using NHibernate and a few other very interesting frameworks like Castle Project and Tarantino.
  • Storefront – Something happened to this project. It is still a good resource though.
  • http://www-asp.net/mvc – Got loads of videos and source code.

So next would be the books I ordered. I can’t recommend any of them yet because I have not read them :)

I know I know, jQuery is not MVC but they are closely related :) 

Tags:

MVC

Generic Repository for Entity Framework

by Mikael Henriksson 26. March 2009 20:42

UPDATE! You might run into problems with pluralized entity set names. Please read this post for an updated version of the generic repository.

I am a very lazy person. I don’t like to repeat myself for boring tasks like data retrieval. I used to code all my repositories by hand but it took away too much of my valuable time so I decided to try out a different approach.

It’s not complete still but the current solution together with MVC makes it real easy to whip up something quickly. This is of course not something I would recommend in a problem domain or if you are in desperate need of performance but I think it is pretty clever so I thought I’d share it with you.

I started off with an interface because I want feel a bit “restricted” with this generic repository of mine.

public interface IRepository : IDisposable
{
	int Add<T>(T entity);
	long Count<T>();
	long Count<T>(ICriterion<T> criterion);
	int Delete<T>(T entity);
	IList<T> GetAll<T>();
	IList<T> GetAll<T>(ICriterion<T> criterion);
	T GetSingle<T>(ICriterion<T> criterion);
	int Update<T>(T entity);
}

The problem with a generic repository comes firstly in the implementation actually. First of all I found it completely impossible to use LiNQ 2 Entities. CreateQuery is the approach I chose. There are some things that exists in this code that you probably for ease of use would remove. I tried the specification pattern but can’t get it to work with OR | or AND &. I am there for not going to post that part yet. You could easily replace the ICriterion<T> parameters with something like:

public void GetAll<T>(Expression<Func<T, bool>> filter)
{
	MyEntities context = GetObjectContext();
	IList<T> entities = context.CreateQuery<T>(
	"[" + typeof (T).Name + "]").Where(filter).ToList();
	ReleaseObjectContextIfNotReused();

	return entities;
}
My issue with this was that I might want multiple criterions. I’ll get back to that at a later stage but for now I’ll show you the whole code. Keep in mind that this is not something I recommend for professional use and particularly not for complex domain driven models but it suits me fine on my spare time :) Oh, and I almost forgot! The RepositoryBase looks like the one in this post

public class Repository : RepositoryBase, IRepository
{
	private bool _disposed;

	public Repository(MyEntities context)
	{
		_context = context;
		_contextReused = true;
	}

	#region IRepository Members

	public int Add<T>(T entity)
	{
		MyEntities context = GetObjectContext();
		context.AddObject(typeof (T).Name, entity);
		int saveValue = context.SaveChanges();
		ReleaseObjectContextIfNotReused();

		return saveValue;
	}

	public long Count<T>()
	{
		MyEntities context = GetObjectContext();
		var query = new ObjectQuery<T>(typeof (T).Name, 
		context, 
		MergeOption.NoTracking);
		int count = query.Count();
		ReleaseObjectContextIfNotReused();

		return count;
	}

	public long Count<T>(ICriterion<T> criterion)
	{
		int count;
		MyEntities context = GetObjectContext();
		
		IQueryable<T> query =
			new ObjectQuery<T>(typeof (T).Name, 
			context, 
			MergeOption.NoTracking).Where(criterion.EvalPredicate);

		count = query.Count();
		ReleaseObjectContextIfNotReused();

		return count;
	}

	public int Delete<T>(T entity)
	{
		MyEntities context = GetObjectContext();

		object originalItem;
		EntityKey key = context.CreateEntityKey(typeof (T).Name, entity);
		if (context.TryGetObjectByKey(key, out originalItem))
		{
			context.DeleteObject(originalItem);
		}
		int returnValue = context.SaveChanges();
		ReleaseObjectContextIfNotReused();

		return returnValue;
	}

	public IList<T> GetAll<T>()
	{
		MyEntities context = GetObjectContext();
		IList<T> entities = context.CreateQuery<T>(
		"[" + typeof (T).Name + "]").ToList();
		ReleaseObjectContextIfNotReused();

		return entities;
	}

	public IList<T> GetAll<T>(ICriterion<T> criterion)
	{
		MyEntities context = GetObjectContext();
		IList<T> entities = context.CreateQuery<T>(
		"[" + typeof (T).Name + "]").Where(
		criterion.EvalPredicate).ToList();
		ReleaseObjectContextIfNotReused();

		return entities;
	}

	public T GetSingle<T>(ICriterion<T> criterion)
	{
		MyEntities context = GetObjectContext();
		T entity = context.CreateQuery<T>("[" + typeof (T).Name + 
		"]").Where(criterion.EvalPredicate).FirstOrDefault();
		ReleaseObjectContextIfNotReused();

		return entity;
	}

	public int Update<T>(T entity)
	{
		MyEntities context = GetObjectContext();

		object originalItem;
		EntityKey key = context.CreateEntityKey(typeof (T).Name, entity);

		if (context.TryGetObjectByKey(key, out originalItem))
		{
			context.ApplyPropertyChanges(key.EntitySetName, entity);
		}
		int returnValue = context.SaveChanges();
		ReleaseObjectContextIfNotReused();

		return returnValue;
	}

	public void Dispose()
	{
		DisposeObject(true);
		GC.SuppressFinalize(this);
	}

	#endregion

	~Repository()
	{
		DisposeObject(false);
	}

	private void DisposeObject(bool disposing)
	{
		if (_disposed)
		{
			return;
		}
		if (disposing)
		{
			if (_context != null)
				_context.Dispose();
		}
		_disposed = true;
	}
}

Tags:

Entity Framework

Entity Framework in asp.net applications

by Mikael Henriksson 11. March 2009 22:50

It is a bit tricky sometimes because of the change tracking. If you start getting / setting data in different object contexts you could end up pressing the save button but not actually saving anything because the object context you use to save changes is actually not the same object context that you made the changes in.

There for I created a base class for my repositories that I can use to handle the creation of the object context.

internal abstract class RepositoryBase
{
	internal ModelEntities _context;
	internal bool _contextReused;

	public ModelEntities GetObjectContext()
	{
		if (!_contextReused)
			return new ModelEntities();

		return _context;
	}

	public void ReleaseObjectContextIfNotReused()
	{
		if (!_contextReused)
			ReleaseObjectContext();
	}

	public void ReleaseObjectContext()
	{
		if (_context != null) _context.Dispose();
		_contextReused = false;
	}
}

So what would be the reason for wanting to reuse the context then? Well let’s say I have an overly complicated way of creating a new entity. I might have to make changes here and there and wait with saving the changes until all steps in the overly complicated way of creating a new entity has been performed. If I open up multiple object contexts not only will performance suffer from instantiating multiple contexts but also… the changes I made won’t stick when I call save changes.

public class Repository : RepositoryBase
{
	public Repository()
	{
		_contextReused = false;
	}

	public Repository(ModelEntities context)
	{
		_contextReused = true;
		_context = context;
	}
	
	public void DoSimpleSomething()
	{
		var context = GetObjectContext();
		var query = from s in context.Something
					select s;
		var summin = query.FirstOrDefault();
		summin.Field = "Value";
		
		var factory = new Factory(context);
		factory.DoComplicatedSomething(summin);

		ReleaseObjectContextIfNotReused();
	}
}
public class Factory : RepositoryBase
{
	public Factory()
	{
		_contextReused = false;
	}

	public Factory(ModelEntities context)
	{
		_contextReused = true;
		_context = context;
	}
	
	public void DoComplicatedSomething(Something summin)
	{
		var context = GetObjectContext();
		summin.SomeReference.Load();
		summin.Some.Field = "whatever"
		' advanced calculations or whatever here
		context.AddToSomething(summin);
		context.SaveChanges();
	}
}

Tags:

Entity Framework