Search code examples
design-patternsrepository-patternservicestackormlite-servicestack

ServiceStack + ORMLite + Repository Pattern


I'm trying to implement the Repository pattern using ORMLite. I initially started off with:

public List<Todo> GetByIds(long[] ids)
{
    using (IDbConnection dbConn = dbFactory.OpenDbConnection())
    {
        return dbConn.Ids<Todo>(ids).ToList();
    }
}

But having this under every method in my Repository seemed a bit repetitive? So I created a data context class which all my repositories inherit from:

public class TodoRepository : DataContext

Here is that DataContext class:

public class DataContext
{
    protected OrmLiteConnectionFactory dbFactory = new 
OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["AppDb"].
ConnectionString, SqlServerOrmLiteDialectProvider.Instance);

    protected IDbConnection dbConn;

    public DataContext()
    {
        dbConn = dbFactory.OpenDbConnection();
    }
}

I then simply have to do this in my methods:

public List<Todo> GetByIds(long[] ids)
{
    return dbConn.Ids<Todo>(ids).ToList();
}

I was just curious if this is a good design pattern and what other's have come up with when using the Repository pattern for data access with ORMLite.


Solution

  • I wouldn't hard-code the strong-type DialectProvider and configuration for the connection in your repository. Instead I would do something that's similar to ServiceStack's base Service class, e.g:

    public class Repository : IDisposable {
    
        public IDbConnectionFactory DbFactory { get; set; } //injected by IOC
    
        IDbConnection db;
        IDbConnection Db 
        { 
            get 
            {
                return db ?? db = DbFactory.Open();
            }
        }
    
        public List<Todo> GetByIds(long[] ids)
        {
            return Db.Ids<Todo>(ids);
        }
    
        public void Dispose() {
            if (db != null)
                db.Dispose();
        }
    }
    

    This way you can initialize the IDbConnectionFactory where it's meant to be, i.e. in the IOC registration of your Host project. In ServiceStack this is in AppHost.Configure():

    container.Register<IDbConnectionFactory>(c => 
        OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["AppDb"].
            ConnectionString, SqlServerDialect.Provider);
    
    container.RegisterAutoWired<Repository>().ReusedWithin(ReuseScope.None);