11

According to this tutorial, to use Ninject in my Asp.net MVC 3 application , all I have to do is install package via Nuget and configure dependencies.

Follow these steps

Install Package-Ninject.MVC3

In NinjectMVC3.cs

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<IReCaptchaValidator>().To<ReCaptchaValidate>();
}

In Controller

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Registe(RegisterModel model)
{
    var myObject = DependencyResolver.Current.GetService<IReCaptchaValidator>(); //always null
}

myObject always returns null.

I've tried kernel.Bind<IReCaptchaValidator>().To<ReCaptchaValidate>().InRequestScope(), but not effect!

myObject continues null

In this post here on StackOverflow, I was told to use DependencyResolver.Current.GetService(TYPE) to retrieve the instance of an object.

Community
  • 1
  • 1
ridermansb
  • 10,779
  • 24
  • 115
  • 226

2 Answers2

4

In the post you refer to, you were not told to use DependencyResolver, just that it's possible to use it. You shouldn't use it, as it's a well known anti-pattern.

While using the DependencyResolver directly should work, you really shouldn't do it that way.

Instead, you should use Constructor Injection, which would be to have your class take the type as a parameter of your constructor.

public class MyController : Controller {
    IReCaptchaValidator _validator;

    public MyController(IReCaptchaValidator validator)
    {
        _validator = validator;
    }
}

Then, in your method:

[HttpPost]  
[ValidateAntiForgeryToken]  
public ActionResult Registe(RegisterModel model)  
{  
    var myObject = _validator;
}  
Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • I had not done this before because I use the ReCaptchaValidator only in thid action, so the DI would instantiate the object in the any action in controller – ridermansb Oct 11 '11 at 02:53
  • @RidermandeSousaBarbosa - I'm sorry, I just don't understand what you're saying. – Erik Funkenbusch Oct 11 '11 at 03:39
  • `ReCaptchaValidate` is used only in `Registe` action. If passed via constructor, it will always be instantiated. Regardless of the action called. – ridermansb Oct 11 '11 at 03:51
  • 2
    @RidermandeSousaBarbosa - while true, it's largely irrelevant. Instantiating it will likely not create much overhead. There are ways to fine tune this, but it's just not worth the effort. – Erik Funkenbusch Oct 11 '11 at 04:00
  • Sorry I know this is old, but I am curious to know why this is a well known anti-pattern. – CGodo May 06 '14 at 19:12
  • @Kyopaxa - Service Resolver is a well known anti-pattern. DependencyResolver is an implementation of ServiceResolver, and if you use DependencyResolver directly (ie.. calling GetService in your code) then you're using an anti-pattern. DependencyResolver is used by the framework to wireup your objects, and this is the correct usage of it. – Erik Funkenbusch May 06 '14 at 19:39
  • 14
    Despite this being the selected answer, I'm forced to down-vote because it didn't actually answer the question. You admit that DependencyResolver should work but then address the approach rather than the problem with the OPs current implementation. – Sinaesthetic Dec 03 '14 at 21:01
  • Doesn't answer the question. This is not what the question was all about, and I'm sick and tired of seeing answers such as "This is not what you should do". – MoonStom Jul 03 '15 at 20:18
  • @MoonStom - Well, the author of the question seems to disagree with you, since he marked it as the answer. We're not here to help you shoot yourself in the foot. We're here to help you write better software, and sometimes that means telling you to not point the gun at your foot and pull the trigger. – Erik Funkenbusch Jul 04 '15 at 00:03
  • 2
    @ErikFunkenbusch true but SO is also used by people like myself who stumble upon same problems but in different circumstances (in my case initializing the app). That is why people should stick to answering the question, not to provide alternatives. Downvoted. – MoonStom Jul 07 '15 at 15:34
  • 1
    @MoonStom - Your problem is different. His problem was in an action method of the site called Register, not in initializing the app... it's a different situation. You can't downvote people because they didn't answer a question YOU want answered in a different circumstance. – Erik Funkenbusch Jul 07 '15 at 15:38
  • 8
    @ErikFunkenbusch The question wasn't about best practices when IOC is used in MVC websites. It was about the DependencyResolver returning NULL for services. Feel free to respond to the question and THEN you can add as many suggestions on good practices as you want. – MoonStom Jul 08 '15 at 18:46
  • 1
    @MoonStom http://stackoverflow.com/help/how-to-answer **The answer can be “don’t do that”, but it should also include “try this instead”.** – Joshua Drake Oct 23 '15 at 16:17
  • 2
    I disagree and was forced to downvote as well. There may sometimes be a legitimate reason why this "anit-pattern" is the most feasible option. In which case this question has been left unanswered. It's a good alternative but does not answer the question. – FernandoZ Apr 17 '18 at 22:33
  • 1
    I'm searching for the solution to the question as stated because I need to resolve a service in Global.asax.cs (my Composition Root). I can't actually do this via constructor injection. To see a non-answer as the accepted answer is frustrating. – Christopher Berman Oct 04 '19 at 14:30
  • Calling this an anti-pattern isn't helpful if you have to do it during startup to, e.g., pass the `IKernel` interface to initialize another component that uses dependency injection, such as Hangfire. (However, in the particular case of the OP, this IS an anti-pattern. The problem is that people find this question with google when they have a valid problem...) – Florian Winter Feb 10 '23 at 14:25
2

I had the same problem. On the same function, I could resolve an interface just fine, while another interface did not resolve. They were both registered!

When resolving manually, it seems that you don't get errors! Pretty funny, but I just found about!

Once I injected the interface in a controller constructor and enabled all exceptions, then I get an exception saying that there was no public constructor for my implementation!

Try that and you will most likely find the root cause.

user2173353
  • 4,316
  • 4
  • 47
  • 79