I am I C#.NET developer for a few years now... Last couple of months I have started to study design patterns and enterprise software architecture principles so that I will be able to use those principles in my code... Well here is actual example what I need. Right now I am developing ASP.net web API REST services. My data is stored in MySQL relational database. In data access layer I would like to use Dapper micro ORM, so I would like to create some kind of my own ORM wrapper methods... If I decide in the future to change to some other ORM that I won't need to rewrite my whole DAL layer code... Here is the code how I am planning to do this: What do you think about my approach? (my goal here is not to be technology (dapper) dependent...)
public abstract class BaseORMCommandSettings //SQL command base class
{
public string CommandText { get; private set; }
public object Parameters { get; private set; }
public IDbTransaction Transaction { get; private set; }
public int? CommandTimeout { get; private set; }
public CommandType? CommandType { get; private set; }
public CancellationToken CancellationToken { get; private set; }
public BaseORMCommandSettings(string commandText, object parameters =
null,
IDbTransaction transaction = null, int? commandTimeout = null,
CommandType? commandType = null, CancellationToken
cancellationToken = default(CancellationToken))
{
this.CommandText = commandText;
this.Parameters = parameters;
this.Transaction = transaction;
this.CommandTimeout = commandTimeout;
this.CommandType = commandType;
this.CancellationToken = cancellationToken;
}
}
public class DapperCommandSettings : BaseORMCommandSettings//dapper cmd impl
{
public CommandFlags Flags { get; private set; }
public DapperCommandSettings(string commandText, object parameters =
null, IDbTransaction transaction = null, int? commandTimeout = null,
CommandType? commandType = null, CancellationToken
cancellationToken = default(CancellationToken), CommandFlags flags =
CommandFlags.Buffered)
:base(commandText, parameters, transaction, commandTimeout,
commandType, cancellationToken)
{
this.Flags = flags;
}
}
public interface ICustomORM //base interface, for now have only generic Read
list method
{
IEnumerable<T> Read<T>(BaseORMCommandSettings cmd);
}
public class DapperORM : ICustomORM //my own dapper ORM wrapper implentation
{
private readonly IDbConnection con;
public DapperORM(IDbConnection con)
{
this.con = con;
}
public IEnumerable<T> Read<T>(BaseORMCommandSettings cmd)
{
var cmdDapper = cmd as DapperCommandSettings;
var dapperCmd = new CommandDefinition(cmdDapper.CommandText,
cmdDapper.Parameters, cmdDapper.Transaction,
cmdDapper.CommandTimeout,
cmdDapper.CommandType, cmdDapper.Flags,
cmdDapper.CancellationToken);
return con.Query<T>(dapperCmd);
}
}
DapperCommandSettings
might be the signal that this abstraction isn't as easy as you imagine. To change ORM is not something you do often or easily. Design patterns should be used when they're appropriate, they're not a mandatory thing to put everywhere. \$\endgroup\$