Ninject - What is the correct way to configure bindings at the model level of an N-Tier MVC3 application domain?

I started using Ninject in an ASP.NET MVC 3 project using the standard boot tape that comes with the nuget package, as shown below.

/// <summary> /// Load your modules or register your services here! /// </summary> /// <param name="kernel">The kernel.</param> private static void RegisterServices(IKernel kernel) { // Documentation for setting up Ninject in ASP.NET MVC3 app: // https://github.com/ninject/ninject.web.mvc/wiki/Setting-up-an-MVC3-application // Add bindings here. No modules required unless we need to add in further // separation of concerns. kernel.Bind<ISessionManager>().To<SessionManager>(); kernel.Bind<ICookieManager>().To<CookieManager>(); kernel.Bind<ILogManager>().To<LogManager>(); kernel.Bind<IStringOutput>().To<StringOutput>(); } 

Within the level of my domain model, there is a class called CookieManager . In my CookieManager class CookieManager I use a class called SecureObjectSerializer .

I want to use dependency injection so that CookieManager not bound to SecureObjectSerializer .

I do not want the MVC project to know about SecureObjectSerializer, setting up bindings, etc. . It seems to be too far from me.

However, I think that within the domain model level the CookieManager should have a SecureObjectSerializer passed in using DI.

My questions:

  • In order for the binding to be registered at the domain model level, do I have to create a Ninject boot block at the domain model level? If so, how do I work it out. I would put a hook and call something like DomainModel.BindModelDependencies(kernel); in the MVC project.

  • When it came time to allow a new instance of the object, what would this code look like? Does this hide when using the MVC loader?

+7
source share
2 answers

You have to put the NinjectModule inside the domain assembly (and not the web assembly), and you can tell ninject about checking your domain assembly and finding the module. a module is just a class that inherits from the NinjectModule base class and implements Load (). Thus, a web project only needs a link to a domain project. The scan should look something like this:

any of these two: (there are actually a few more options, but these are the main ones that I use)

 var assemblysToScan = "Assembly.*"; var assemblysToScan = new[] { "Assembly.Domain", "Assembly.Web" }; 

and then just

 kernel.Scan(x => { x.From(assemblysToScan) x.AutoLoadModules(); }); 

If you want to allow an object, just put it as the ctor argument, and if ninject controls you objects, it automatically enters the type (based on the configured bindings).

EDIT:

add links to ninjectcommonservicelocator (don't remember the exact name) and microsoft.practices.servicelocation

in your boot block add the following:

 using Microsoft.Practices.ServiceLocation; using CommonServiceLocator.NinjectAdapter; var locator = new NinjectServiceLocator(kernel); ServiceLocator.SetLocatorProvider(() => locator); 

then in your class:

 using Microsoft.Practices.ServiceLocation; class CookieManager : ICookieManager { SecureObjectSerialiser secureObjectSerialiser; CookieManager() { this.secureObjectSerialiser = ServiceLocator.Current.GetInstance<SecureObjectSerialiser>(); } } 

The reason for the microsoft.practices locator is that your code should not know that ninject works under covers. instead, you use a generic servicelocator, which can be reused if you change containers.

personally, I would avoid this and just enter everything. but if you cannot, you cannot.

+6
source

The accepted answer relates to the Scan() method of Ninject.Extensions.Conventions . Ninject 3.0 has replaced it with a more powerful free interface to perform dynamic assembly bindings.

  kernel.Bind(x => x .FromAssembliesMatching("*") .SelectAllClasses() .BindDefaultInterface()); 

Adventure continues in the Wiki extension .

+3
source

All Articles