We are currently using dapper ORM to access data by calling store procedures. The current code is having a class BusinessFunctions which inherits another class DataFunctions which are having helper methods to execute the stored procedures.
I am not happy with this code. It's just too rigid and not future proof. And above all it's not coded to an interface rather coded to an implementation. I propose an interface IRepository with an abstract class Repository which implements all helper generic methods. Then I create BusinessRepository that implements the abstract Repository class and call the generic helpers method. Again, my colleague is telling me to remove the IRepository interface and just use the Repository abstract class.
public class BusinessFunctions : DataFunctions
{
public BusinessFunctions(ConnectionManager conMgr, LogWriter logWriter, AppUser appUser) : base(conMgr, logWriter, appUser)
{
}
public async Task<Business> FindAsync(int businessId)
{
throw new NotImplementedException();
}
public async Task<Business> FindAsync(string businessGuid)
{
var lst = await StoredProcQueryAsync<Business>("spBusinessGetSetupGUID", new { BusinessGuid = businessGuid });
if (lst.Count() == 0)
throw new NotFoundInDatabaseException("Business", businessGuid);
else
return lst.Single();
}
public async Task<bool> IsHostedTokenizeCardAllowedAsync(string businessGuid)
{
var b = await FindAsync(businessGuid);
if (b.HostedPaymentEnabled)
return true;
else
return false;
}
}
public class DataFunctions : IDisposable
{
private ConnectionManager _conMgr;
private LogWriter _logWriter;
private AppUser _appUser;
public ConnectionManager ConnMgr
{
get { return _conMgr; }
}
protected LogWriter Logger
{
get { return _logWriter; }
}
protected AppUser User
{
get { return _appUser; }
}
public DataFunctions(ConnectionManager conMgr, LogWriter logWriter, AppUser appUser)
{
_conMgr = conMgr;
_logWriter = logWriter;
_appUser = appUser;
}
public void Dispose()
{
}
public async Task StoredProcExecuteNonQueryAsync(string storedProc,
List<StoredProcParameter> storedProcParameters = null,
SqlCommandTimeout commandTimeout = SqlCommandTimeout.Default,
SqlAccessType accessType = SqlAccessType.ReadWrite
)
{
using (SqlConnection conn = new SqlConnection(ConnMgr.SqlConnectionString))
{
await conn.OpenAsync();
await StoredProcExecuteNonQueryAsync(conn,
storedProc,
storedProcParameters: storedProcParameters,
commandTimeout: commandTimeout,
accessType: accessType);
}
}
public async Task StoredProcExecuteNonQueryAsync(SqlConnection conn,
string storedProc,
List<StoredProcParameter> storedProcParameters = null,
SqlCommandTimeout commandTimeout = SqlCommandTimeout.Default,
SqlAccessType accessType = SqlAccessType.ReadWrite,
SqlTransaction trans = null
)
{
using (SqlCommand cmd = new SqlCommand(storedProc, conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = (int)commandTimeout;
if (trans != null) cmd.Transaction = trans;
if (storedProcParameters != null)
{
foreach(var p in storedProcParameters)
{
cmd.Parameters.Add(p.ToSqlParameter());
}
}
await cmd.ExecuteNonQueryAsync();
}
}
public async Task<IEnumerable<T>> StoredProcQueryAsync<T>(string storedProc,
object storedProcParameters = null,
SqlCommandTimeout commandTimeout = SqlCommandTimeout.Default,
SqlAccessType accessType = SqlAccessType.ReadWrite)
{
using (SqlConnection conn = new SqlConnection(ConnMgr.SqlConnectionString))
{
conn.Open();
return await StoredProcQueryAsync<T>(conn,
storedProc,
storedProcParameters,
commandTimeout);
}
}
public async Task<IEnumerable<T>> StoredProcQueryAsync<T>(SqlConnection conn,
string storedProc,
object storedProcParameters = null,
SqlCommandTimeout commandTimeout = SqlCommandTimeout.Default)
{
return await conn.QueryAsync<T>(storedProc,
commandType: CommandType.StoredProcedure,
commandTimeout: (int)commandTimeout,
param: storedProcParameters);
}
}