lucamilan
4/27/2012 - 12:56 PM

Code for my post on Repository Pattern for Entity Framework: http://coderjournal.com/2010/11/entity-framework-repository-pattern/

Code for my post on Repository Pattern for Entity Framework: http://coderjournal.com/2010/11/entity-framework-repository-pattern/

	public class RepositorySession : IRepositorySession
	{
		public static Type DefaultContainerType { get; set; }

		[ThreadStatic] 
		private static RepositorySession _current;

		public static RepositorySession Current
		{
			get { return _current; }
			protected set { _current = value; }
		}

		private bool _disposed;
		private IObjectContext _container;

		public RepositorySession()
		{
			if (Current != null)
				throw new ApplicationException("There is already an active session, a new one cannot be created.");

			_container = Activator.CreateInstance(DefaultContainerType) as IObjectContext;
			Current = this;
		}

		public RepositorySession(IObjectContext container)
		{
			_container = container;
		}

		public IObjectContext Container
		{
			get { return _container; }
		}

		public bool LazyLoadingEnabled
		{
			get
			{
				DisposedCheck();
				return _container.ContextOptions.LazyLoadingEnabled;
			}
			set
			{
				DisposedCheck();
				_container.ContextOptions.LazyLoadingEnabled = value;
			}
		}

		public bool ProxyCreationEnabled
		{
			get
			{
				DisposedCheck();
				return _container.ContextOptions.ProxyCreationEnabled;
			}
			set
			{
				DisposedCheck();
				_container.ContextOptions.ProxyCreationEnabled = value;
			}
		}

		#region ISession Members

		public void Commit()
		{
			_container.SaveChanges();
		}

		#endregion

		private void DisposedCheck()
		{
			if (_disposed)
				throw new ObjectDisposedException(ToString());
		}

		#region IDisposable Members

		/// <summary>
		/// 
		/// </summary>
		public void Dispose()
		{
			Dispose(true);
		}

		/// <summary>
		/// The dispose.
		/// </summary>
		/// <param name="disposing">
		/// The disposing.
		/// </param>
		protected virtual void Dispose(bool disposing)
		{
			if (!_disposed && disposing)
			{
				if (_container != null)
					_container.Dispose();

				if (Current == this)
					Current = null;
			}

			_disposed = true;
		}

		/// <summary>
		/// Finalizes an instance of the <see cref="CassandraSession"/> class. 
		/// </summary>
		~RepositorySession()
		{
			Dispose(false);
		}

		#endregion
	}
	public static class RepositoryHelper
	{
		public static IQueryable<T> Include<T>(this IQueryable<T> source, string path)
		{
			if (source is ObjectQuery<T>)
				return ((ObjectQuery<T>)source).Include(path);

			return source;
		}
	}
	public abstract class Repository<T> : IRepository<T>
		where T : class
	{
		private IObjectContext _container;
		private IObjectSet<T> _objectSet;

		public Repository(IRepositorySession session)
		{
			Session = session;
			_container = Session.Container;
		}

		protected IRepositorySession Session { get; private set; }

		private IObjectSet<T> ObjectSet
		{
			get
			{
				if (_objectSet == null)
					_objectSet = _container.CreateObjectSet<T>();

				return _objectSet;
			}
		}

		#region IRepository<T> Members

		public IQueryable<T> All()
		{
			return ObjectSet;
		}

		public IQueryable<T> Where(Expression<Func<T, bool>> predicate)
		{
			return ObjectSet.Where(predicate);
		}

		public virtual T Create()
		{
			return _container.CreateObject<T>();
		}

		public virtual void Add(T entity)
		{
			ObjectSet.AddObject(entity);
		}

		public virtual void Delete(T entity)
		{
			ObjectSet.DeleteObject(entity);
		}

		public void Attach(T entity)
		{
			ObjectSet.Attach(entity);
		}

		public void Detach(T entity)
		{
			ObjectSet.Detach(entity);
		}

		#endregion
	}
	public interface IRepositorySession : IDisposable
	{
		IObjectContext Container { get; }
		void Commit();
	}
	public interface IRepository<TEntity>
	{
		IQueryable<TEntity> All();
		IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> expression);

		TEntity Create();

		void Add(TEntity entity);
		void Delete(TEntity entity);

		void Attach(TEntity entity);
		void Detach(TEntity entity);
	}
	public interface IObjectContext : IDisposable
	{
		ObjectContextOptions ContextOptions { get; }

		TEntity CreateObject<TEntity>() where TEntity : class;
		IObjectSet<TEntity> CreateObjectSet<TEntity>() where TEntity : class;

		int SaveChanges();
	}