Repository of trainers
It has been suggested in docs to not pass IConfiguration around for injection. Try creating a IConnectionFactory or just have a connection injected directly into the repo

Something like

public interface IDbConnectionFactory {
   IDbConnection CreateConnection();
}


and its implementation for your class would look something like this

public class SqlConnectionFactory : IDbConnectionFactory {
    private readonly string dbConnectionString;

    public SqlConnectionFactory(string dbConnectionString) {
        this.dbConnectionString = dbConnectionString;
    }

    public IDbConnection CreateConnection() {
        return new SqlConnection(this.dbConnectionString);
    }
}


it would be registered in startup

var connectionString = Configuration.GetConnectionString("MyConnString");
services.AddScoped&lt;IDbConnectionFactory, SqlConnectionFactory&gt;(_ =&gt; new SqlConnectionFactory(connectionString));

//...


and injected

public class TrainerRepo : IRepoTrainer {
    private readonly IDbConnectionFactory factory;

    public TrainerRepo(IDbConnectionFactory factory) {
        this.factory = factory;
    }

    public List&lt;Trainer&gt; GetTrainers() {
        string sql = "select trainer_id,trainer_name from trainer";
        using(IDbConnection connection = factory.CreateConnection()) {
            connection.Open();
            var res = connection.Query&lt;Trainer&gt;(sql).ToList&lt;Trainer&gt;();
            connection.Close();
            return res;
        }
    }

    //...


The repeated code can also be generalized

T Invoke&lt;T&gt;(Func&lt;IDbConnection, T&gt; func) {
    using(IDbConnection connection = factory.CreateConnection()) {
        connection.Open();
        var res = func(connection);
        connection.Close();
        return res;
    }
}

async Task&lt;TResult&gt; InvokeAsync&lt;TResult&gt;(Func&lt;IDbConnection, Task&lt;TResult&gt;&gt; func) {
    using(IDbConnection connection = factory.CreateConnection()) {
        connection.Open();
        var res = await func(connection);
        connection.Close();
        return res;
    }
}


Which changes the previous examples to

public List&lt;Trainer&gt; GetTrainers() {
    string sql = "select trainer_id,trainer_name from trainer";
    return Invoke(connection =&gt; connection.Query&lt;Trainer&gt;(sql).ToList&lt;Trainer&gt;());
}


public Task&lt;int&gt; updateTrainer(Trainer trainer) {
    string sql = "update trainer set trainer_name = @tname where trainer_id = @tid";
    return  InvokeAsync(connection =&gt; connection.ExecuteAsync(sql, param: new { tname = trainer.trainer_name, tid = trainer.trainer_id }));
}