Repository + Unit Of Work Pattern in WebAPI











up vote
0
down vote

favorite












I am refactoring my existing product's webapi part of the solution. Current Repo pattern does not allow me to add custom functions to a specific repository. In result, most of the functions directly use the Db context in the controller.



I read various articles and come up a good way of implementation to achieve my targets and also best practice. Here I am posting my sample implementation to review and some more guidelines. I don't know if you can help me to review from git repository as I am new to this forum.



Aim/Targets:




  1. Need a generic way of repository and Unit of work pattern so that code can be reused with the advantage of the Repository pattern.

  2. I also have custom functions to each repository and the pattern should accept this extension.


Current Limitations/Future Plans:




  1. The current implementation does not have dependency injection so I am not making complex now. Will check in near future due to the impact.


  2. The current implementation does not use the business layer. So repository class directly calling from API controller. Here I can't check deep into the business functions now so will look into future.



Code:



Now please look into my implementation



Project Structure



Project structure



Data Project Code:



public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
public PaginatedList(IEnumerable<T> source, int pageNumber, int pageSize, int totalCount)
{

if (source == null)
{
throw new ArgumentNullException("source");
}

if (pageSize <= 0)
{
throw new ArgumentException("pageSize");
}

AddRange(source);

PageNumber = pageNumber < 1 ? 1 : pageNumber;
PageSize = pageSize;
TotalCount = totalCount;
TotalPageCount = (int)Math.Ceiling(totalCount / (double)pageSize);
}
public int PageNumber { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPageCount { get; private set; }

public bool HasPreviousPage
{

get
{
return (PageNumber > 1);
}
}

public bool HasNextPage
{

get
{
return (PageNumber < TotalPageCount);
}
}

}
public SampleContext() : base("Name=SampleContext")
{

}
public IDbSet<User> Users { get; set; }
public IDbSet<Item> Items { get; set; }

}


Repository Project Code:



Interfaces



    public interface IRepository<T> where T : class
{
Task<IEnumerable<T>> GetAll();
Task<PaginatedList<T>> GetPaged(Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, int pageIndex, int pageSize, Expression<Func<T, bool>> filter = null, IList<Expression<Func<T, object>>> includedProperties = null);
Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>> expression);
Task<T> Get(object id);
void Create(T entity);
void Update(T entity);
}
public interface IUnitOfWork
{
IUserRepository Users { get; }
IItemRepository Items { get; }
void SaveAsync();
}
public interface IUserRepository : IRepository<User>
{
User GetByName(string name);
}

public interface IItemRepository : IRepository<Item>
{
}


Repositories



public abstract class Repository<T> : IRepository<T>
where T : class
{
private readonly DbSet<T> _dbSet;

protected SampleContext Context { get; set; }

protected Repository(SampleContext context)
{
Context = context;
_dbSet = Context.Set<T>();
}

public virtual async Task<IEnumerable<T>> GetAll()
{
return await _dbSet.ToListAsync();
}

public virtual async Task<PaginatedList<T>> GetPaged(Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, int pageIndex, int pageSize, Expression<Func<T, bool>> filter = null, IList<Expression<Func<T, object>>> includedProperties = null)
{
var query = orderBy(_dbSet);
int totalCount = query.Count();
var collection = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
return new PaginatedList<T>(collection, pageIndex, pageSize, totalCount);
}


public virtual async Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>> expression)
{
return await _dbSet.Where(expression).ToListAsync();
}

public virtual async Task<T> Get(object id)
{
return await _dbSet.FindAsync(id);
}


public virtual void Create(T entity)
{
_dbSet.Add(entity);
}

public virtual void Update(T entity)
{
_dbSet.Attach(entity);
Context.Entry(entity).State = EntityState.Modified;
}

}
public class UserRepository : Repository<User>, IUserRepository
{
public UserRepository(SampleContext context) : base(context)
{

}
public User GetByName(string name)
{
return Context.Users.FirstOrDefault(x => x.Name == name);
}
}
public ItemRepository(SampleContext context) : base(context)
{
}


API ProjectCode:



    public class BaseController : ApiController
{
protected IUnitOfWork UnitOfWork { get; set; }
public BaseController()
{
UnitOfWork = new UnitOfWork();
}
}
public class UserController : BaseController
{
public UserController()
{
}

[Route("api/users/all", Name = "UsersCollection")]
public async Task<IHttpActionResult> GetAll([FromUri]int page = 1, int pageSize = 20)
{
var items = await UnitOfWork.Users.GetPaged(x => x.OrderBy(y => y.Id), page, pageSize);
//Add mapping to DTO
return Ok(items);
}

[Route("api/users/{name}", Name = "UserByName")]
public IHttpActionResult GetByName(string name)
{
var item = UnitOfWork.Users.GetByName(name);
if(item == null)
{
return StatusCode(HttpStatusCode.NoContent);
}
//Add mapping to DTO
return Ok(item);
}

}


My Questions:




  1. Please review my project structure, namings, and implementation for any code smell?


  2. I didn't create an interface for Paginated List because of the private set. Please suggest any good approach for this if any? Also, this class is not part of the database but I keep it in the Model folder itself.


  3. Any code smell in the use of UnitOfWork class initialization in the base controller? If so, while initializing all repositories in the UnitOFWork class is initialized unnecessarily?


  4. UnitOfWork class is implemented IDisposable so can I implement dispose in the base controller to dispose UniOfWork class? As I implement IDisposable in the class itself, I can't use dispose method from IUnitOfWork interface object











share|improve this question







New contributor




Akhil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    0
    down vote

    favorite












    I am refactoring my existing product's webapi part of the solution. Current Repo pattern does not allow me to add custom functions to a specific repository. In result, most of the functions directly use the Db context in the controller.



    I read various articles and come up a good way of implementation to achieve my targets and also best practice. Here I am posting my sample implementation to review and some more guidelines. I don't know if you can help me to review from git repository as I am new to this forum.



    Aim/Targets:




    1. Need a generic way of repository and Unit of work pattern so that code can be reused with the advantage of the Repository pattern.

    2. I also have custom functions to each repository and the pattern should accept this extension.


    Current Limitations/Future Plans:




    1. The current implementation does not have dependency injection so I am not making complex now. Will check in near future due to the impact.


    2. The current implementation does not use the business layer. So repository class directly calling from API controller. Here I can't check deep into the business functions now so will look into future.



    Code:



    Now please look into my implementation



    Project Structure



    Project structure



    Data Project Code:



    public class User
    {
    public int Id { get; set; }
    public string Name { get; set; }
    }
    public class Item
    {
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    }
    public PaginatedList(IEnumerable<T> source, int pageNumber, int pageSize, int totalCount)
    {

    if (source == null)
    {
    throw new ArgumentNullException("source");
    }

    if (pageSize <= 0)
    {
    throw new ArgumentException("pageSize");
    }

    AddRange(source);

    PageNumber = pageNumber < 1 ? 1 : pageNumber;
    PageSize = pageSize;
    TotalCount = totalCount;
    TotalPageCount = (int)Math.Ceiling(totalCount / (double)pageSize);
    }
    public int PageNumber { get; private set; }
    public int PageSize { get; private set; }
    public int TotalCount { get; private set; }
    public int TotalPageCount { get; private set; }

    public bool HasPreviousPage
    {

    get
    {
    return (PageNumber > 1);
    }
    }

    public bool HasNextPage
    {

    get
    {
    return (PageNumber < TotalPageCount);
    }
    }

    }
    public SampleContext() : base("Name=SampleContext")
    {

    }
    public IDbSet<User> Users { get; set; }
    public IDbSet<Item> Items { get; set; }

    }


    Repository Project Code:



    Interfaces



        public interface IRepository<T> where T : class
    {
    Task<IEnumerable<T>> GetAll();
    Task<PaginatedList<T>> GetPaged(Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, int pageIndex, int pageSize, Expression<Func<T, bool>> filter = null, IList<Expression<Func<T, object>>> includedProperties = null);
    Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>> expression);
    Task<T> Get(object id);
    void Create(T entity);
    void Update(T entity);
    }
    public interface IUnitOfWork
    {
    IUserRepository Users { get; }
    IItemRepository Items { get; }
    void SaveAsync();
    }
    public interface IUserRepository : IRepository<User>
    {
    User GetByName(string name);
    }

    public interface IItemRepository : IRepository<Item>
    {
    }


    Repositories



    public abstract class Repository<T> : IRepository<T>
    where T : class
    {
    private readonly DbSet<T> _dbSet;

    protected SampleContext Context { get; set; }

    protected Repository(SampleContext context)
    {
    Context = context;
    _dbSet = Context.Set<T>();
    }

    public virtual async Task<IEnumerable<T>> GetAll()
    {
    return await _dbSet.ToListAsync();
    }

    public virtual async Task<PaginatedList<T>> GetPaged(Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, int pageIndex, int pageSize, Expression<Func<T, bool>> filter = null, IList<Expression<Func<T, object>>> includedProperties = null)
    {
    var query = orderBy(_dbSet);
    int totalCount = query.Count();
    var collection = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
    return new PaginatedList<T>(collection, pageIndex, pageSize, totalCount);
    }


    public virtual async Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>> expression)
    {
    return await _dbSet.Where(expression).ToListAsync();
    }

    public virtual async Task<T> Get(object id)
    {
    return await _dbSet.FindAsync(id);
    }


    public virtual void Create(T entity)
    {
    _dbSet.Add(entity);
    }

    public virtual void Update(T entity)
    {
    _dbSet.Attach(entity);
    Context.Entry(entity).State = EntityState.Modified;
    }

    }
    public class UserRepository : Repository<User>, IUserRepository
    {
    public UserRepository(SampleContext context) : base(context)
    {

    }
    public User GetByName(string name)
    {
    return Context.Users.FirstOrDefault(x => x.Name == name);
    }
    }
    public ItemRepository(SampleContext context) : base(context)
    {
    }


    API ProjectCode:



        public class BaseController : ApiController
    {
    protected IUnitOfWork UnitOfWork { get; set; }
    public BaseController()
    {
    UnitOfWork = new UnitOfWork();
    }
    }
    public class UserController : BaseController
    {
    public UserController()
    {
    }

    [Route("api/users/all", Name = "UsersCollection")]
    public async Task<IHttpActionResult> GetAll([FromUri]int page = 1, int pageSize = 20)
    {
    var items = await UnitOfWork.Users.GetPaged(x => x.OrderBy(y => y.Id), page, pageSize);
    //Add mapping to DTO
    return Ok(items);
    }

    [Route("api/users/{name}", Name = "UserByName")]
    public IHttpActionResult GetByName(string name)
    {
    var item = UnitOfWork.Users.GetByName(name);
    if(item == null)
    {
    return StatusCode(HttpStatusCode.NoContent);
    }
    //Add mapping to DTO
    return Ok(item);
    }

    }


    My Questions:




    1. Please review my project structure, namings, and implementation for any code smell?


    2. I didn't create an interface for Paginated List because of the private set. Please suggest any good approach for this if any? Also, this class is not part of the database but I keep it in the Model folder itself.


    3. Any code smell in the use of UnitOfWork class initialization in the base controller? If so, while initializing all repositories in the UnitOFWork class is initialized unnecessarily?


    4. UnitOfWork class is implemented IDisposable so can I implement dispose in the base controller to dispose UniOfWork class? As I implement IDisposable in the class itself, I can't use dispose method from IUnitOfWork interface object











    share|improve this question







    New contributor




    Akhil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am refactoring my existing product's webapi part of the solution. Current Repo pattern does not allow me to add custom functions to a specific repository. In result, most of the functions directly use the Db context in the controller.



      I read various articles and come up a good way of implementation to achieve my targets and also best practice. Here I am posting my sample implementation to review and some more guidelines. I don't know if you can help me to review from git repository as I am new to this forum.



      Aim/Targets:




      1. Need a generic way of repository and Unit of work pattern so that code can be reused with the advantage of the Repository pattern.

      2. I also have custom functions to each repository and the pattern should accept this extension.


      Current Limitations/Future Plans:




      1. The current implementation does not have dependency injection so I am not making complex now. Will check in near future due to the impact.


      2. The current implementation does not use the business layer. So repository class directly calling from API controller. Here I can't check deep into the business functions now so will look into future.



      Code:



      Now please look into my implementation



      Project Structure



      Project structure



      Data Project Code:



      public class User
      {
      public int Id { get; set; }
      public string Name { get; set; }
      }
      public class Item
      {
      public int Id { get; set; }
      public string Name { get; set; }
      public decimal Price { get; set; }
      }
      public PaginatedList(IEnumerable<T> source, int pageNumber, int pageSize, int totalCount)
      {

      if (source == null)
      {
      throw new ArgumentNullException("source");
      }

      if (pageSize <= 0)
      {
      throw new ArgumentException("pageSize");
      }

      AddRange(source);

      PageNumber = pageNumber < 1 ? 1 : pageNumber;
      PageSize = pageSize;
      TotalCount = totalCount;
      TotalPageCount = (int)Math.Ceiling(totalCount / (double)pageSize);
      }
      public int PageNumber { get; private set; }
      public int PageSize { get; private set; }
      public int TotalCount { get; private set; }
      public int TotalPageCount { get; private set; }

      public bool HasPreviousPage
      {

      get
      {
      return (PageNumber > 1);
      }
      }

      public bool HasNextPage
      {

      get
      {
      return (PageNumber < TotalPageCount);
      }
      }

      }
      public SampleContext() : base("Name=SampleContext")
      {

      }
      public IDbSet<User> Users { get; set; }
      public IDbSet<Item> Items { get; set; }

      }


      Repository Project Code:



      Interfaces



          public interface IRepository<T> where T : class
      {
      Task<IEnumerable<T>> GetAll();
      Task<PaginatedList<T>> GetPaged(Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, int pageIndex, int pageSize, Expression<Func<T, bool>> filter = null, IList<Expression<Func<T, object>>> includedProperties = null);
      Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>> expression);
      Task<T> Get(object id);
      void Create(T entity);
      void Update(T entity);
      }
      public interface IUnitOfWork
      {
      IUserRepository Users { get; }
      IItemRepository Items { get; }
      void SaveAsync();
      }
      public interface IUserRepository : IRepository<User>
      {
      User GetByName(string name);
      }

      public interface IItemRepository : IRepository<Item>
      {
      }


      Repositories



      public abstract class Repository<T> : IRepository<T>
      where T : class
      {
      private readonly DbSet<T> _dbSet;

      protected SampleContext Context { get; set; }

      protected Repository(SampleContext context)
      {
      Context = context;
      _dbSet = Context.Set<T>();
      }

      public virtual async Task<IEnumerable<T>> GetAll()
      {
      return await _dbSet.ToListAsync();
      }

      public virtual async Task<PaginatedList<T>> GetPaged(Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, int pageIndex, int pageSize, Expression<Func<T, bool>> filter = null, IList<Expression<Func<T, object>>> includedProperties = null)
      {
      var query = orderBy(_dbSet);
      int totalCount = query.Count();
      var collection = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
      return new PaginatedList<T>(collection, pageIndex, pageSize, totalCount);
      }


      public virtual async Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>> expression)
      {
      return await _dbSet.Where(expression).ToListAsync();
      }

      public virtual async Task<T> Get(object id)
      {
      return await _dbSet.FindAsync(id);
      }


      public virtual void Create(T entity)
      {
      _dbSet.Add(entity);
      }

      public virtual void Update(T entity)
      {
      _dbSet.Attach(entity);
      Context.Entry(entity).State = EntityState.Modified;
      }

      }
      public class UserRepository : Repository<User>, IUserRepository
      {
      public UserRepository(SampleContext context) : base(context)
      {

      }
      public User GetByName(string name)
      {
      return Context.Users.FirstOrDefault(x => x.Name == name);
      }
      }
      public ItemRepository(SampleContext context) : base(context)
      {
      }


      API ProjectCode:



          public class BaseController : ApiController
      {
      protected IUnitOfWork UnitOfWork { get; set; }
      public BaseController()
      {
      UnitOfWork = new UnitOfWork();
      }
      }
      public class UserController : BaseController
      {
      public UserController()
      {
      }

      [Route("api/users/all", Name = "UsersCollection")]
      public async Task<IHttpActionResult> GetAll([FromUri]int page = 1, int pageSize = 20)
      {
      var items = await UnitOfWork.Users.GetPaged(x => x.OrderBy(y => y.Id), page, pageSize);
      //Add mapping to DTO
      return Ok(items);
      }

      [Route("api/users/{name}", Name = "UserByName")]
      public IHttpActionResult GetByName(string name)
      {
      var item = UnitOfWork.Users.GetByName(name);
      if(item == null)
      {
      return StatusCode(HttpStatusCode.NoContent);
      }
      //Add mapping to DTO
      return Ok(item);
      }

      }


      My Questions:




      1. Please review my project structure, namings, and implementation for any code smell?


      2. I didn't create an interface for Paginated List because of the private set. Please suggest any good approach for this if any? Also, this class is not part of the database but I keep it in the Model folder itself.


      3. Any code smell in the use of UnitOfWork class initialization in the base controller? If so, while initializing all repositories in the UnitOFWork class is initialized unnecessarily?


      4. UnitOfWork class is implemented IDisposable so can I implement dispose in the base controller to dispose UniOfWork class? As I implement IDisposable in the class itself, I can't use dispose method from IUnitOfWork interface object











      share|improve this question







      New contributor




      Akhil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I am refactoring my existing product's webapi part of the solution. Current Repo pattern does not allow me to add custom functions to a specific repository. In result, most of the functions directly use the Db context in the controller.



      I read various articles and come up a good way of implementation to achieve my targets and also best practice. Here I am posting my sample implementation to review and some more guidelines. I don't know if you can help me to review from git repository as I am new to this forum.



      Aim/Targets:




      1. Need a generic way of repository and Unit of work pattern so that code can be reused with the advantage of the Repository pattern.

      2. I also have custom functions to each repository and the pattern should accept this extension.


      Current Limitations/Future Plans:




      1. The current implementation does not have dependency injection so I am not making complex now. Will check in near future due to the impact.


      2. The current implementation does not use the business layer. So repository class directly calling from API controller. Here I can't check deep into the business functions now so will look into future.



      Code:



      Now please look into my implementation



      Project Structure



      Project structure



      Data Project Code:



      public class User
      {
      public int Id { get; set; }
      public string Name { get; set; }
      }
      public class Item
      {
      public int Id { get; set; }
      public string Name { get; set; }
      public decimal Price { get; set; }
      }
      public PaginatedList(IEnumerable<T> source, int pageNumber, int pageSize, int totalCount)
      {

      if (source == null)
      {
      throw new ArgumentNullException("source");
      }

      if (pageSize <= 0)
      {
      throw new ArgumentException("pageSize");
      }

      AddRange(source);

      PageNumber = pageNumber < 1 ? 1 : pageNumber;
      PageSize = pageSize;
      TotalCount = totalCount;
      TotalPageCount = (int)Math.Ceiling(totalCount / (double)pageSize);
      }
      public int PageNumber { get; private set; }
      public int PageSize { get; private set; }
      public int TotalCount { get; private set; }
      public int TotalPageCount { get; private set; }

      public bool HasPreviousPage
      {

      get
      {
      return (PageNumber > 1);
      }
      }

      public bool HasNextPage
      {

      get
      {
      return (PageNumber < TotalPageCount);
      }
      }

      }
      public SampleContext() : base("Name=SampleContext")
      {

      }
      public IDbSet<User> Users { get; set; }
      public IDbSet<Item> Items { get; set; }

      }


      Repository Project Code:



      Interfaces



          public interface IRepository<T> where T : class
      {
      Task<IEnumerable<T>> GetAll();
      Task<PaginatedList<T>> GetPaged(Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, int pageIndex, int pageSize, Expression<Func<T, bool>> filter = null, IList<Expression<Func<T, object>>> includedProperties = null);
      Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>> expression);
      Task<T> Get(object id);
      void Create(T entity);
      void Update(T entity);
      }
      public interface IUnitOfWork
      {
      IUserRepository Users { get; }
      IItemRepository Items { get; }
      void SaveAsync();
      }
      public interface IUserRepository : IRepository<User>
      {
      User GetByName(string name);
      }

      public interface IItemRepository : IRepository<Item>
      {
      }


      Repositories



      public abstract class Repository<T> : IRepository<T>
      where T : class
      {
      private readonly DbSet<T> _dbSet;

      protected SampleContext Context { get; set; }

      protected Repository(SampleContext context)
      {
      Context = context;
      _dbSet = Context.Set<T>();
      }

      public virtual async Task<IEnumerable<T>> GetAll()
      {
      return await _dbSet.ToListAsync();
      }

      public virtual async Task<PaginatedList<T>> GetPaged(Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, int pageIndex, int pageSize, Expression<Func<T, bool>> filter = null, IList<Expression<Func<T, object>>> includedProperties = null)
      {
      var query = orderBy(_dbSet);
      int totalCount = query.Count();
      var collection = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
      return new PaginatedList<T>(collection, pageIndex, pageSize, totalCount);
      }


      public virtual async Task<IEnumerable<T>> FindByAsync(Expression<Func<T, bool>> expression)
      {
      return await _dbSet.Where(expression).ToListAsync();
      }

      public virtual async Task<T> Get(object id)
      {
      return await _dbSet.FindAsync(id);
      }


      public virtual void Create(T entity)
      {
      _dbSet.Add(entity);
      }

      public virtual void Update(T entity)
      {
      _dbSet.Attach(entity);
      Context.Entry(entity).State = EntityState.Modified;
      }

      }
      public class UserRepository : Repository<User>, IUserRepository
      {
      public UserRepository(SampleContext context) : base(context)
      {

      }
      public User GetByName(string name)
      {
      return Context.Users.FirstOrDefault(x => x.Name == name);
      }
      }
      public ItemRepository(SampleContext context) : base(context)
      {
      }


      API ProjectCode:



          public class BaseController : ApiController
      {
      protected IUnitOfWork UnitOfWork { get; set; }
      public BaseController()
      {
      UnitOfWork = new UnitOfWork();
      }
      }
      public class UserController : BaseController
      {
      public UserController()
      {
      }

      [Route("api/users/all", Name = "UsersCollection")]
      public async Task<IHttpActionResult> GetAll([FromUri]int page = 1, int pageSize = 20)
      {
      var items = await UnitOfWork.Users.GetPaged(x => x.OrderBy(y => y.Id), page, pageSize);
      //Add mapping to DTO
      return Ok(items);
      }

      [Route("api/users/{name}", Name = "UserByName")]
      public IHttpActionResult GetByName(string name)
      {
      var item = UnitOfWork.Users.GetByName(name);
      if(item == null)
      {
      return StatusCode(HttpStatusCode.NoContent);
      }
      //Add mapping to DTO
      return Ok(item);
      }

      }


      My Questions:




      1. Please review my project structure, namings, and implementation for any code smell?


      2. I didn't create an interface for Paginated List because of the private set. Please suggest any good approach for this if any? Also, this class is not part of the database but I keep it in the Model folder itself.


      3. Any code smell in the use of UnitOfWork class initialization in the base controller? If so, while initializing all repositories in the UnitOFWork class is initialized unnecessarily?


      4. UnitOfWork class is implemented IDisposable so can I implement dispose in the base controller to dispose UniOfWork class? As I implement IDisposable in the class itself, I can't use dispose method from IUnitOfWork interface object








      c# repository asp.net-web-api






      share|improve this question







      New contributor




      Akhil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Akhil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Akhil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 38 mins ago









      Akhil

      1011




      1011




      New contributor




      Akhil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Akhil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Akhil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.



























          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          Akhil is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209884%2frepository-unit-of-work-pattern-in-webapi%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          Akhil is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          Akhil is a new contributor. Be nice, and check out our Code of Conduct.













          Akhil is a new contributor. Be nice, and check out our Code of Conduct.












          Akhil is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209884%2frepository-unit-of-work-pattern-in-webapi%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Quarter-circle Tiles

          build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

          Mont Emei