views:

106

answers:

2

I have an ASP.NET MVC project which uses a services project to go through a set of interfaces (project) to a repository project.

I am slightly confused where to use Ninject. It seems logical to me that i include my Ninject in the services layer as this is where i interact with the interfaces.

My question is how would this be implemented? Also, how have other people implemented this?

+1  A: 

In your Services project you'll want to create a class that derives from NinjectModule and override the Load method; this class's responsibility is to register your dependencies with Ninject.

public class ServiceModule : NinjectModule
{
    public override void Load() {
        Bind<IAccountService>().To<AccountService>();
    }
}

Then, you'll want to make an Application class that inherits from NinjectHttpApplication. Override the CreateKernel method and register the NinjectModule from your Services project (along with any others you may need to register.

public class MvcApplication : NinjectHttpApplication
{
    protected override void OnApplicationStarted() {
        RegisterRoutes(RouteTable.Routes);
        RegisterAllControllersIn(Assembly.GetExecutingAssembly());
    }

    protected override IKernel CreateKernel() {
        var modules = new INinjectModule[] {
            new MyProject.Services.ServiceModule(),
            new MyProject.Data.DataModule()
        };

        var kernel = new StandardKernel(modules);

        return kernel;
    }
qstarin
note, to use NinjectHttpApplication, you'll need the extension code: http://github.com/ninject/ninject.web.mvc
dave thieben
+1  A: 

Theoretically, the only the place to use a DI container is in the setup of the project. in the case of an ASP.NET MVC project, that would be in the Global.asax's Application_Start method. For my project, I am using a NInject based ControllerFactory to instantiate controllers as needed, and then the controllers have whatever dependencies they need in their constructors so NInject hooks them up appropriately.

my global.asax:

    private static IKernel kernel = new StandardKernel();
    protected void Application_Start()
    {
        kernel.Bind<IRepository<User>>().To<NHibernateRepository<User>>();

        ControllerBuilder.Current.SetControllerFactory( new NinjectControllerFactory( kernel ) );
    }

and my NInjectControllerFactory:

public class NinjectControllerFactory : System.Web.Mvc.DefaultControllerFactory
{
    private IKernel container;

    public NinjectControllerFactory( IKernel container )
    {
        this.container = container;
    }

    protected override IController GetControllerInstance( RequestContext requestContext, Type controllerType )
    {
        if ( controllerType != null )
        {
            IController controller = container.Get( controllerType ) as IController;
            Check.Require( controller, "Could not instantiate controller type: {0}", controllerType.FullName );
            return controller;
        }

        return base.GetControllerInstance( requestContext, controllerType );
    }
}
dave thieben