Search code examples
asp.net-mvcrepositoryasp.net-web-apiunit-of-work

MVC unit of work and repository not working for me


I have a web api set up to get companies from a data base.

namespace Bloginect.Controllers
{

public abstract class ApiControlerBase : ApiController
{
    protected BloginectUow Uow { get; set; }
}

public class CompanyController : ApiControlerBase
{
    // Dependancy set up with Ninject
    public CompanyController(BloginectUow uow)
    {
        Uow = uow;
    }

    // GET api/company
    public IEnumerable<Company> Get()
    {     
        *-------- Uow.companies is null here ----------*
        return Uow.companies.GetCompanies();
    }
}
}

I am getting a null exception for companies on the line

return Uow.companies.GetCompanies();

The unit of work class holds a company repository and it is set up as follows

namespace Bloginect.Data
{
public class BloginectUow : IDisposable
{
    private BloginectDbContext DbContext = new BloginectDbContext();
    public ICompanyRepository companies { get; set; }      

    public void Commit()
    {
        DbContext.SaveChanges();            
    }        

}
}

The company repository interfaceis set up as follows

public interface ICompanyRepository : IRepository<Company>
    {
        /// <summary>
        /// Gets companies
        /// </summary>
        /// <returns></returns>
        IQueryable<Company> GetCompanies();
    }

IRepository<Company>

is just a standard repository with crud operations

Can anyone see a problem and why is the ICompanyRepository not getting initiated.


Solution

  • You need to initialize your repository. Take a look at the samples how could you do this:

    1º Solution - Not Generic implementation... you can do some specific and complex queries on this scenario for each entity.

    public class BloginectUow : IDisposable
    {
        private BloginectDbContext DbContext = new BloginectDbContext();
    
        public ICompanyRepository Companies { get; set; }      
    
        // constructor
        public BloginectUow()
        {
            // initialize your repository..
            Companies = new CompanyRepository();
        }
    
        /// methods...
    }
    

    In this case you have to have a class to implement your ICompanyRepository interface:

    public class CompanyRepository : ICompanyRepository {
    
       // methods of the interface to data access... from entity framework or nhibernate or ado.net or whatever...
    
    }
    

    2º Solution - Or, you could use an generic repository:

    public class BloginectUow : IDisposable
    {
        private BloginectDbContext DbContext = new BloginectDbContext();
    
        public IRepository<Company> Companies { get; set; }      
    
        // constructor
        public BloginectUow()
        {
            // initialize your repository with a generic implementation..
            Companies = new Repository<Company>();
        }
    
        /// methods...
    }
    

    In the second case, you have to have a Repository<T> class (which need to have CRUD operations... for sample) and use a interface of this class on your UnitOfWork.

    Doing this way, you will get a generic implementation of your DataAccess but you could not to do complex queries when you need. If you need to do complex queries I would recommend you to get a single implementation of Repository for each entity, inherits if from a generic repository and implement method to do complex queries, that's a good pratice.