0

I'm trying to move the query logic out of my controllers. My problem is context is null and is throwing an exception in my concrete class PetRepository when I try and get a list of pets.

In the interface:

    public interface IPetRepository
    {
    List<Pet> GetAllPets();   
    PetStoreContext context { get; set; }
    }

In the concrete implementation:

public class PetRepository : IPetRepository
{
    public PetStoreContext context { get; set; }

    public List<Pet> GetAllPets()
    {
        return context.Pet.ToList(); //this line throws a null exception
    }
 }

In my controller I'm using constructor injection:

public class PetsController : BaseController
{
    private IPetRepository _petRepository;

    public PetsController(IPetRepository petRepository)
    {
        _petRepository = petRepository;
    }
 }

Then my action result

public ActionResult Index()
    {            
        var model = new PetListing()
        {
            Pets = _petRepository.GetAllPets()
         }
       return View(model);
     }

And finally I am just doing a simple mapping with autofac.

  private void RegisterAutoFac()
    {
        var builder = new ContainerBuilder();
        builder.RegisterControllers(Assembly.GetExecutingAssembly());
        builder.RegisterSource(new ViewRegistrationSource());

        builder.RegisterType<PetRepository>().As<IPetRepository>();

        var container = builder.Build();

        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

    }

If I use the same lines of code in my controller directly then I get a list of pets back from the DB e.g

public ActionResult Index()
{
 public PetStoreContext context = new PetStoreContext();    
return View(context.Pet.ToList());
}
JKerny
  • 488
  • 1
  • 3
  • 19

1 Answers1

2

context is a property not being set, instead let IoC instantiate it for you by injecting it into your repo:

public class PetRepository : IPetRepository
{
    private readonly PetStoreContext _context;

    public PetRepository(PetStoreContext context)
    {
        _context = context;
    }

    public List<Pet> GetAllPets()
    {
        return _context.Pet.ToList();
    }
 }
Lockdowne
  • 474
  • 3
  • 7
  • Thanks. I'm new to IOC. Is there another piece to the puzzle. Now I'm getting one of those confusing IOC run time errors when I call my controller : None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'PetStore.Repository.PetRepository' can be invoked with the available services and parameters: Cannot resolve parameter 'PetStore.PetStore.DAL.Context.PetStoreContext context' of constructor 'Void .ctor(PetStore.PetStore.DAL.Context.PetStoreContext)'. – JKerny Jun 24 '17 at 08:31
  • It looks like you will need to register the context with `Autofac` https://stackoverflow.com/questions/29560294/inject-dbcontext-with-autofac – Lockdowne Jun 24 '17 at 08:39
  • Your original answer was correct. I wasn't instantiating context. I resolved this by making a BaseRepository interface with a concrete implementation that newed up context. Then I used IOC to pass the BaseRepo into the PetRepo constructor and Bob's you uncle. Thanks again – JKerny Jun 25 '17 at 05:15