# Auto-generated generic data layer

I'm trying to make a reusable data layer that is mostly generated from a database via T4 templates. On top of this data layer, I'd like to have WebAPI endpoints for each repository, with most of the basic CRUD operations generated/from a base class. The generics are somewhat getting out of hand, and I don't know if I'm trying to build too much of a swiss army knife here.

Starting at the bottom, I have an entity class (some bits truncated):

public class Entity<T>
{
public T Id { get; set; }
}


A T4 template runs a SQL statement to pull out database schema, and spits out a file with a bunch of classes along the lines of:

public partial class Visit : Entity<int>
{
//Fields on the table
}


Generated along side these entity classes are corresponding repositories, all implementing this interface:

public interface IRepository<TEntity, in TKey> where TEntity: Entity<TKey>
{
// Other Methods
}


These get filled out with proper SQL statements for the action. Specific repositories can have additional methods as needed.

This bit I'm happy with, it's easy to understand, and the code generators for it aren't complicated. Where it starts getting complicated is when I move up into the WebAPI Controllers.

All data access is handled from a Unit of Work, which handles connection and transaction lifetimes. Currently, there are individual properties for each repository, and this is done via a T4 template:

public partial class RulesWorkUnit : ITransactionWorkUnit
{
public RulesWorkUnit(DbConnectionFactory connectionFactory)
{
_Visit = new Lazy<VisitRepository>(() => new VisitRepository(_conn, _tran));
}

public VisitRepository Visit { get { return _Visit.Value; } }
}


This part I also like, and is what I've been doing for a bit for data access, and works well for the cases where I'm coding by hand.

Now, here's where it starts going off of the rails a bit. I have a base API Controller class. This needs to know which repository to create, so that goes in as a generic parameter. This parameter needs to go down to the Work Unit so it knows which repository to return, that results in this code added to the work unit:

//Member variable
private Dictionary<Type, Func<dynamic>> _repositoryTypes;

_repositoryTypes[typeof(VisitRepository)] = () => new VisitRepository(_conn, _tran);

//New Method
public TRepository GetRepository<TRepository, TEntity, TKey>()
where TRepository : class, IRepository<TEntity, TKey>
where TEntity : Entity<TKey>
{
return _repositoryTypes[typeof (TRepository)] as TRepository;
}


This is where the generic definitions start exploding. The base API controller is one worse, since it also needs to know the model to map to:

public abstract class RepositoryApiController<TRepository, TModel, TEntity, TKey> : ApiController
where TRepository : class, IRepository<TEntity, TKey>
where TEntity : Entity<TKey>


Which starts setting off my code smell alarms. I would like somehow to manage the boilerplate code for most of the basic API methods (they'll all have a Get All, Get By Id, Post, Put, Delete that have the same code, with the exception of the entity type and the return model type).

Is there a better way of designing this?

• Are you using an ORM? It would be nice to see some implementations, and the truncated bits too (including the class bodies). – Mathieu Guindon Jun 3 '14 at 16:54