4
\$\begingroup\$

Almost all of generic repository pattern tutorials were making use of EF, so I haven't got much sources to compare my code with. Here is what I have done. Could you please suggest me to fix my wrongs if I have or improve the code?

Note: I am using Dapper.Net as ORM, and I am aware of Dapper.Contrib dll, I just want to implement my own methods.

Generic Repository class

public interface IRepository<T> where T : BaseEntity
{
    IDbConnection Connection { get; set; }
    void Insert(T entity);
    void Delete(T entity);
    T GetById(int id);
    IQueryable<T> GetAll();
}

A Repository Class

public interface ICustomerRepository : IRepository<Customer>
{

}

public class CustomerRepository : ICustomerRepository
{
    public IDbConnection Connection { get; set; }

    public CustomerRepository()
    {
        Connection = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ConnectionString);
    }

    public void Delete(Customer entity)
    {
        try
        {
            using (Connection)
            {
                Connection.Execute("DELETE FROM dbo.Customer Where Id = @Id", new { entity.Id });
            }
        }
        catch (Exception ex)
        {

        }
    }

    public IQueryable<Customer> GetAll()
    {
        IQueryable<Customer> list = new List<Customer>().AsQueryable();

        try
        {
            using (Connection)
            {
                list = Connection.Query<Customer>("SELECT * FROM dbo.Customer").AsQueryable();
            }
        }
        catch (Exception ex)
        {

        }
        return list;
    }

    public Customer GetById(int id)
    {
        Customer customer = new Customer();
        try
        {
            using (Connection)
            {
                customer = Connection.Query<Customer>("SELECT * FROM dbo.Customer WHERE Id = @Id", new { Id = id }).SingleOrDefault();
            }
        }
        catch (Exception ex)
        {

        }
        return customer;
    }

    public void Insert(Customer entity)
    {
        try
        {
            using (Connection)
            {
                Connection.Execute("INSERT INTO dbo.Customer VALUES(@FullName, @TcNo, @BirthDate)",
                    new
                    {
                        entity.FullName,
                        entity.Tcno,
                        entity.BirthDate
                    });
            }
        }
        catch (Exception ex)
        {

        }
    }
}

An Api Controller

public class CustomerController : ApiController
{
    private IRepository<Customer> _customerRepo;

    public CustomerController()
    {
        _customerRepo = new CustomerRepository(new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ConnectionString));
    }
    [HttpGet]
    [Route("")]
    public IHttpActionResult Get()
    {
        return Json(_customerRepo.GetAll());
    }
}
\$\endgroup\$
9
  • 5
    \$\begingroup\$ Why did you decide to ignore all exceptions? Don't you want to know what went wrong? \$\endgroup\$
    – t3chb0t
    Oct 10, 2017 at 6:46
  • \$\begingroup\$ Actually those blocks are not implemented yet. I will just simply log the exceptions. If you have any suggestion on this I would love to know. \$\endgroup\$
    – ibubi
    Oct 10, 2017 at 7:00
  • \$\begingroup\$ Normally a Generic Repository has also an Update Method. And if you add this Method, you should think about adding a locking mechanism (optimistic or pessimistic) if you have a multi user environment. \$\endgroup\$ Oct 10, 2017 at 14:25
  • \$\begingroup\$ @VolkmarRigo isn't the UoW responsibility to handle transactions? \$\endgroup\$ Oct 10, 2017 at 18:56
  • \$\begingroup\$ @AdrianIftode since this repository is used in an API Controller, reading an entity and updating/deleting an entity are 2 different service calls. Therefore normally you have to add some logic to assure, that you update/delete an entity only if the entity wasn't changed by someone else after you read it. \$\endgroup\$ Oct 11, 2017 at 9:56

1 Answer 1

5
\$\begingroup\$

I think you are in the right direction but let me suggest some things.

Remove the try catch and let the repository throw the exception. Either that or catch and throw your own exception.

Inject IDbConnection in the constructor of the repository and remove the using on the repository methods

    private IDbConnection _connection;

    public CustomerRepository(IDbConnection connection)
    {
        _connection = connection;
    }

Probably you want to use the repository in this way in many scenarios and with your current implementation you lose the transaction scope.

    public void DoWork()
    {
        using (var connection = ...)
        {
            //begin transaction
            var repository = new CustomerRepository(connection);
            var otherRepository = new OtherRepository(connection)
            var customer = repository.GetById(2);
            //do some stuff
            otherRepository.Update()...
            repository.Delete(customer);
            //commit transaction
        }
    }

This can be combined with IoC container.

\$\endgroup\$
3
  • \$\begingroup\$ I was thinking of moving try-catchto up level (controllers), thanks. Btw, I updated the question, added controller side which calls the repo classes. I think it is still not transaction-friendly, is it? I should consider the way you did that create dowork method and wrap it with a single connection for transactions inside all actions in my controllers if needed. \$\endgroup\$
    – ibubi
    Oct 10, 2017 at 9:47
  • 1
    \$\begingroup\$ Not only transactions, but I guess if you do two calls to the repository it will fail as conection is disposed. Your controller looks good. Consider wire all the things with an IoC container as MVC plays very good with it. Enjoy :) \$\endgroup\$
    – ogomrub
    Oct 10, 2017 at 10:25
  • \$\begingroup\$ I had to have a break for a while, now I am onto this again, I wonder how to combine transactions via IoC container. Because, I am using Unity for IoC currently. Do you have any tutorial or guidence for this? \$\endgroup\$
    – ibubi
    Oct 18, 2017 at 6:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.