Ninject binds various implementations

I have been using Ninject for a short time, and I'm trying to figure out how to do something that I did in Unity with the entries app.config / web.config.

I am sure that this is simple, just did not find the best way to implement it, and, of course, Ninject does not have the largest documentation.

I want to have different implementations for the interface, without changing the code - a specific application knows which implementation to use.

For example, when I used Unity, I would have a live application and a unit test library using different data libraries. So:

var repo = IoC.Get<IRepository>(); 

will return RealRepository in my live application and FakeRepository in my unit tests. I would just map the classes in my app.config or web.config.

In Ninject, since you define mappings in the code, there is no way to decide which implementations (or which module) you use, with the exception of the code, but of course, the whole purpose - I want to specifically indicate which implementation I want to use.

Is there a good way to do this? The only way I can imagine is to dynamically select the NinjectModule implementation from the configuration file, but that is simply not the case.

+4
source share
2 answers

It sounds like you are missing an IoC container as a service locator. This gives you a lot of problems. One of them is that testing is much more complicated. I suggest doing this directly instead, and making a design ban instead of a service location.

It means instead

 public class MyClass { public void Do() { var repo = IoC.Get<IRepository>(); .... } } 

you do

 public class MyClass { private IRepository repo; public MyClass(IRepository repo) { this.repo = repo; } public void Do() { .... } } 

There is only one Get for the root of your application. Everything else is passed through the constructors.

This makes testing very simple:

 var testee = new MyClass(new Mock<IRepository>()); 
+8
source

Don't your live application and your unit test libraries have different endpoints? One of them is supposedly a unit test (nunit?) Project, and the other is an application (console, windows, or asp.net).

Each type of application must independently determine its bindings, usually defining separate modules (which you pass to the StandardKernel constructor). One set provides mappings for your real application, and the other provides mappings for your unit tests. The latter may or may not be necessary - ideally, the dependencies of the particular class you are testing should be easily ridiculed and passed without using Ninject. In practice, I found many excuses when it was convenient to use Ninject, in which case I create a separate module or just rebuild the kernel on the fly in the test itself.

+2
source

All Articles