DependencyResolver.Current.GetService always returns null
Asked Answered
V

2

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.

Venesection answered 10/10, 2011 at 23:50 Comment(2)
I have a similar problem. On the same function, I can resolve an interface just fine, while another interface does not resolve. They are both registered! Go figure...!Grader
Aha! Fixed it! Check the answers!Grader
V
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;
}  
Violaviolable answered 11/10, 2011 at 1:51 Comment(16)
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 controllerVenesection
@RidermandeSousaBarbosa - I'm sorry, I just don't understand what you're saying.Violaviolable
ReCaptchaValidate is used only in Registe action. If passed via constructor, it will always be instantiated. Regardless of the action called.Venesection
@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.Violaviolable
Sorry I know this is old, but I am curious to know why this is a well known anti-pattern.Atop
@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.Violaviolable
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.Teammate
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".Holomorphic
@Holomorphic - 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.Violaviolable
@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.Holomorphic
@Holomorphic - 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.Violaviolable
@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.Holomorphic
@Holomorphic stackoverflow.com/help/how-to-answer The answer can be “don’t do that”, but it should also include “try this instead”.Simulate
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.Scabble
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.Conformist
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...)Instable
G
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.

Grader answered 28/5, 2020 at 10:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.