ServiceStack + ORMLite +存储库模式

时间:2013-01-23 12:53:31

标签: design-patterns repository-pattern servicestack ormlite-servicestack

我正在尝试使用ORMLite实现Repository模式。我最初开始时:

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

但是在我的Repository中的每个方法下都有这个似乎有点重复?所以我创建了一个数据上下文类,我的所有存储库都继承自:

public class TodoRepository : DataContext

这是DataContext类:

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

    protected IDbConnection dbConn;

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

然后我只需要在我的方法中执行此操作:

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

我很好奇这是一个很好的设计模式,以及在使用存储库模式与ORMLite进行数据访问时所提出的其他模式。

2 个答案:

答案 0 :(得分:8)

我不会对存储库中的连接强类型DialectProvider和配置进行硬编码。相反,我会做一些类似于ServiceStack的基础Service类的事情,例如:

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();
    }
}

通过这种方式,您可以初始化IDbConnectionFactory所在的位置,即在您的主机项目的IOC注册中。在ServiceStack中,这是AppHost.Configure()

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

container.RegisterAutoWired<Repository>().ReusedWithin(ReuseScope.None); 

答案 1 :(得分:2)

我知道这是一个老问题,但我认为我已经填上了。我的服务访问IGenericRepository<T>访问IDatabaseContext(可能是使用System.Data.IDbConnection的任何内容,但在这种情况下,ServiceStack的OrmLite)又使用了ServiceStack的IDbConnectionFactory

public class GenericRepository<T> : IGenericRepository<T>
    where T : class
{
    private readonly IDatabaseContext _databaseContext;

    public GenericRepository(IDatabaseContext databaseContext)
    {
        _databaseContext = databaseContext;
    }

    public T Get(int id)
    {
        return _databaseContext.Query(db =>
            {
                return db.SingleById<T>(id);
            });
    }

    public async Task<T> GetAsync(int id)
    {
        return await _databaseContext.QueryAsync(async db =>
        {
            return await db.SingleByIdAsync<T>(id);
        });
    }

    // other methods (All, First, etc)
}

IDbConnectionFactory注册为

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

OrmLite的IDatabaseContext

public class OrmLiteDatabaseContext : IDatabaseContext
{
    private readonly IDbConnectionFactory _dbConnectionFactory;

    public DatabaseContext(IDbConnectionFactory dbConnectionFactory)
    {
        _dbConnectionFactory = dbConnectionFactory;
    }

    public T Query<T>(Func<IDbConnection, T> query)
    {
        using (var connection = _dbConnectionFactory.OpenDbConnection())
        {
            return query(connection);
        }
    }

    public async Task<T> QueryAsync<T>(Func<IDbConnection, Task<T>> query)
    {
        using (var connection = _dbConnectionFactory.OpenDbConnection())
        {
            return await query(connection);
        }
    }
}

效果很好。