title: Repository Pattern Implementation Experience
body: <p>I am getting ready to start a new asp.net web project, and I am going to LINQ-to-SQL. I have done a little bit of work getting my data layer setup using some info I found by <a href="http://mikehadlow.blogspot.com/" rel="nofollow noreferrer" title="Mike Hadlow">Mike Hadlow</a> that uses an Interface and generics to create a Repository for each table in the database. I thought this was an interesting approach at first. However, now I think it might make more sense to create a base Repository class and inherit from it to create a TableNameRepository class for the tables I need to access.  </p>
  
  <p>Which approach will be allow me to add functionality specific to a Table in a clean testable way? Here is my Repository implementation for reference.</p>
  
  <pre><code>public class Repository&lt;T&gt; : IRepository&lt;T&gt; where T : class, new()
  {
      protected IDataConnection _dcnf;
  
      public Repository()
      {
          _dcnf = new DataConnectionFactory() as IDataConnection;
      }
  
      // Constructor injection for dependency on DataContext 
      // to actually connect to a database
      public Repository(IDataConnection dc)
      {
          _dcnf = dc;
      }
  
      /// &lt;summary&gt;
      /// Return all instances of type T.
      /// &lt;/summary&gt;
      /// &lt;returns&gt;IEnumerable&lt;T&gt;&lt;/returns&gt;
      public virtual IEnumerable&lt;T&gt; GetAll()
      {
          return GetTable;
      }
  
      public virtual T GetById(int id)
      {
          var itemParam = Expression.Parameter(typeof(T), "item");
          var whereExp = Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;
              (
                  Expression.Equal(
                      Expression.Property(itemParam, PrimaryKeyName),
                      Expression.Constant(id)
                  ), new ParameterExpression[] { itemParam }
              );
          return _dcnf.Context.GetTable&lt;T&gt;().Where(whereExp).Single();
      }
  
      /// &lt;summary&gt;
      /// Return all instances of type T that match the expression exp.
      /// &lt;/summary&gt;
      /// &lt;param name="exp"&gt;&lt;/param&gt;
      /// &lt;returns&gt;IEnumerable&lt;T&gt;&lt;/returns&gt;
      public virtual IEnumerable&lt;T&gt; FindByExp(Func&lt;T, bool&gt; exp)
      {
          return GetTable.Where&lt;T&gt;(exp);
      }
  
      /// &lt;summary&gt;See IRepository.&lt;/summary&gt;
      /// &lt;param name="exp"&gt;&lt;/param&gt;&lt;returns&gt;&lt;/returns&gt;
      public virtual T Single(Func&lt;T, bool&gt; exp)
      {
          return GetTable.Single(exp);
      }
  
      /// &lt;summary&gt;See IRepository.&lt;/summary&gt;
      /// &lt;param name="entity"&gt;&lt;/param&gt;
      public virtual void MarkForDeletion(T entity)
      {
          _dcnf.Context.GetTable&lt;T&gt;().DeleteOnSubmit(entity);
      }
  
      /// &lt;summary&gt;
      /// Create a new instance of type T.
      /// &lt;/summary&gt;
      /// &lt;returns&gt;T&lt;/returns&gt;
      public virtual T Create()
      {
          //T entity = Activator.CreateInstance&lt;T&gt;();
          T entity = new T();
          GetTable.InsertOnSubmit(entity);
          return entity;
      }
  
      /// &lt;summary&gt;See IRepository.&lt;/summary&gt;
      public virtual void SaveAll()
      {
          _dcnf.SaveAll();
      }
  
      #region Properties
      private string PrimaryKeyName
      {
          get { return TableMetadata.RowType.IdentityMembers[0].Name; }
      }
  
      private System.Data.Linq.Table&lt;T&gt; GetTable
      {
          get { return _dcnf.Context.GetTable&lt;T&gt;(); }
      }
  
      private System.Data.Linq.Mapping.MetaTable TableMetadata
      {
          get { return _dcnf.Context.Mapping.GetTable(typeof(T)); }
      }
  
      private System.Data.Linq.Mapping.MetaType ClassMetadata
      {
          get { return _dcnf.Context.Mapping.GetMetaType(typeof(T)); }
      }
      #endregion
  }
  </code></pre>