views:

90

answers:

1

I'm using asp.net MVC 2 and Ninject 2.

The setup is very simple. Controller calls service that calls repository.

In my controller I use inject to instantiate the service classes with no problem. But the service classes don't instantiate the repositories, giving me NullReferenceException.

public class BaseController : Controller
{
    [Inject]
    public IRoundService roundService { get; set; }
}

This works. But then this does not...

public class BaseService
{
    [Inject]
    public IRoundRepository roundRepository { get; set; }
}

Giving a NullReferenceException, when I try to use the roundRepository in my RoundService class.

IList<Round> rounds = roundRepository.GetRounds( );

Module classes... public class ServiceModule : NinjectModule { public override void Load( ) { Bind( ).To( ).InRequestScope( ); } }

public class RepositoryModule : NinjectModule
{
    public override void Load( )
    {
        Bind<IRoundRepository>( ).To<RoundRepository>( ).InRequestScope( );
    }
}

In global.axax.cs

protected override IKernel CreateKernel( )
{
        return new StandardKernel( new ServiceModule( ),
            new RepositoryModule( )  );
}
A: 

Sorry, I can't answer why that isn't working the way it should but have you thought about using constructor injection?

That's how I do my dependency injection with Ninject 2 & ASP.NET MVC 2 and it works all the way down the chain from controller -> service -> repository & beyond.

It also makes sense to me to have the dependencies in the constructor for your object. It makes these dependencies highly visible and obvious to any other object that has to instantiate it. Otherwise you may end up with null reference exceptions... kinda like you have here.

HTHs,
Charles

EDIT: Showing base class injection through constructors in response to the comments.

public class BaseService
{
    public IRoundRepository RoundRepo { get; private set; }

    public BaseService(IRoundRepository roundRepo)
    {
        RoundRepo = roundRepo;
    }
}

public class SquareService : BaseService
{
    public ISquareRepository SquareRepo { get; private set; }

    public SquareService(ISquareRepository squareRepo, IRoundRepository roundRepo)
        : base(roundRepo)
    {
        SquareRepo = squareRepo;
    }
}

This is just my way of doing things... someone else may have a different idea / opinion.

Charlino
Yeah, that worked if I put the constructor injection in the main service class, not in the base class. I guess that's because the constructor with the parameters in the base class never gets called, just the default parameter-less one. I'm new to all this IOC/DI but it is making me think about things in a new way which is good.
Iceman
If your base class has a dependency then I wouldn't have a parameter-less constructor because again, you're hiding the dependencies. Rather have your derived classes call the correct constructor. I'll edit my answer to give an example.
Charlino