DependencyResolver.Current.GetService always returns null - c#

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.

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;
}

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.

Related

An unhandled exception occurred while processing the request in ASP.NET Core dependency injection

I have an ASP.NET Core Web application that has an interface in the application that inherits a class from the interface.
I am trying to use the interface by dependency injection in the controller constructor, but I always get the following error
An unhandled exception occurred while processing the request.
InvalidOperationException: Unable to resolve service for type
'DependenceInjection_Dapper.Services.SendSMS' while attempting to
activate 'DependenceInjection_Dapper.Controllers.HomeController'.
Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider
sp, Type type, Type requiredBy, bool isDefaultParameterRequired)
The interface codes are as follows:
public interface IsmsSender
{
string sendSms();
}
The class codes are as follows:
public class SendSms : IsmsSender
{
public string sendSms()
{
return "send sms";
}
}
And the following code is added in the program.cs file:
builder.Services.AddTransient<IsmsSender, SendSms>();
Also, the manufacturer of the controller is as follows:
public class HomeController : Controller
{
private readonly IsmsSender _smsSender;
public HomeController(SendSms smsSender)
{
_smsSender = smsSender;
}
public IActionResult Index()
{
ViewBag.send = _smsSender.sendSms();
return View();
}
}
However, I always get an error.
I behaved exactly according to the Microsoft documentation, but the problem was not solved.
You are injecting the concrete type instead of the interface, which is what you registered. Do this instead:
public class HomeController : Controller
{
private readonly IsmsSender _smsSender;
public HomeController(IsmsSender smsSender)
{
_smsSender = smsSender;
}
public IActionResult Index()
{
ViewBag.send = _smsSender.sendSms();
return View();
}
}
Always keep in mind that what matters for the container is the "registration type", not the concrete type. What this line says:
builder.Services.AddTransient<IsmsSender, SendSms>();
Is basically:
Whenever someone asks for an IsmsSender, give a SendSms instance to them
Nothing is said about consumers asking for SendSms.
It is possible to register the concrete type itself, though that's not usual and not recommended when you already have an abstraction in place: you want to rely on abstractions instead of concrete classes to reduce coupling in your implementation and make it more testable.
To register the concrete class itself, you'd just omit the first generic parameter:
builder.Services.AddTransient<SendSms>();
This now means that people must ask for SendSms directly, and IsmsSender won't be resolvable anymore.
The problem comes from your consturctor
public HomeController(SendSms smsSender)
{
_smsSender = smsSender;
}
should be
public HomeController(ISendSms smsSender)
{
_smsSender = smsSender;
}
you registred your ISmendSms as Sendsms in the depenency injection phase.

Dependency Injection in ASP.NET MVC

I've been using Dependency Injection in ASP.NET MVC the way I've explained in the below code, but I'm not sure if that is the right and standard way to do it. So I just wanna know if what I'm doing is wrong or if there is a better and more professional way to do it.
public interface IService {
public Boolean AddRecord(Object _Model);
}
public class Employee: IService {
DataBase Context = new DataBase();
public Boolean AddRecord(Object _Model) {
Context.Add((EmployeeModel) _Model);
return Context.SaveChanges() != 0;
}
}
public class DataController: Controller {
IService service;
public DataController(IService service) {
this.service = service;
}
public ActionResult AddRecord(Object _Model, String Caller) {
if (service.Add(_Model)) {
TempData["Result"] = "Data Added";
return RedirectToAction(Caller);
}
TempData["Result"] = "Please try again";
return View (Caller, _Model);
}
}
When I wanna use the controller with the DI, I do: (Is this the right way to consume the DataController)
public class TestController: Controller {
public ActionResult Index () {
return View();
}
public ActionResult TestIt (EmployeeModel _Model) {
DataController DC = new DataController(new Employee());
return DC.AddRecord(_Model, "../Test/TestIt");
}
}
You have the general concept of Dependency Injection / Inversion down. That is, you've understood that instead of this:
public class Example {
public void SomeFunc() {
var service = new Service();
service.DoStuff();
}
}
..you do this:
public class Example {
private readonly IService _service;
public Example(IService service) {
_service = service;
}
public void SomeFunc() {
_service.DoStuff();
}
}
.. and you supply the dependency manually via the calling code.. such as a Controller:
public HomeController : Controller {
[HttpGet]
public ActionResult Index() {
var example = new Example(new Service());
example.SomeFunc();
// .. the rest ..
}
}
So, the first part is Dependency Inversion. You have inverted the dependency chain from being top down to bottom up. The second part (the above code block) is Dependency Injection.
Notice in the above block of code that the Controller has no dependencies injected. This is where Inversion of Control comes in.
Inversion of Control is a pattern where code completely external to the currently running code decides how it functions. In this context, it means some external code - somewhere else - decides how to supply dependencies to your controller.
(Note, I am quite familiar with Ninject - so the below examples are using Ninject. There are plenty of other available DI/IoC containers available)
Ninject is a framework that can help with this (and many others). Ninject has an extension for ASP.NET MVC which automatically builds and supplies controller instances for you - plus your dependencies.
Without providing a full tutorial on using Ninject (which I will leave as an exercise to the OP to Google), the basics of it is this.
You declare a "module" with the configuration for your dependencies. Using the above examples, your module might look like this:
public class YourModule : NinjectModule {
public override void Load() {
Bind<IExample>().To<Example>().InRequestScope();
Bind<IService>().To<Service>().InRequestScope();
}
}
This will wire up all requests for an IExample to an Example, and IService to an instance of a Service. So your Controller would become:
public class HomeController : Controller {
private readonly IExample _example;
public HomeController(IExample example) {
_example = example;
}
[HttpGet]
public ActionResult Index() {
_example.SomeFunc();
// .. the rest ..
}
}
The container (in this case, Ninject) looks at your external code (the YourModule class) and determines what IExample should be. It sees that you've said it should be an instance of an Example class. Example also requires a dependency of type IService. So Ninject will again look at YourModule and determines that it should be an instance of Service. It continues to go down the object hierarchy until it completes the construction of the objects.
Hopefully that makes sense - it is definitely hard to explain these concepts in text.
I haven't viewed this video (I am running off of really really terrible WiFi hotspot while I wait for an internet connection!) so I can't verify it's quality, but a quick Google search turned this up for setting up Ninject and MVC: http://www.youtube.com/watch?v=w_MehI2qBTo
You would definitely benefit from Googling around some Inversion of Control and/or Ninject videos to understand what frameworks like it are for.
It is important to note too that frameworks like Ninject can also control scope. In the example above, I used InRequestScope against the bindings. This means that Ninject will instantiate the dependency at the start of the web request - and dispose of it afterward. This removes the need for you to worry about that.

Object reference not set to an instance of an object error!

Can anyone see what I'm doing wrong here? I'm trying to learn how to have specs/ services and domain projects in general but in this case it's ASP.NET MVC.
I have the following code in my controller but I getting Object reference not set to an instance of an object on the following line of code. I would appreciate any suggestions where I'm going wrong!?
// Error
Line 22: var profiles = _profileService.GetProfile();
// code below
namespace Whitepages.Controllers
{
[HandleError]
public class HomeController : Controller
{
private readonly IProfileService _profileService;
public HomeController(IProfileService profileService)
{
_profileService = profileService;
}
public HomeController()
{
}
public ActionResult Index()
{
var profiles = _profileService.GetProfile();
return View("Index");
}
}
}
using Domain;
namespace Services.Spec
{
public interface IProfileService
{
Profile GetProfile();
}
}
Many thanks,
It looks like the controller factory you are using to build your controllers passes null at the constructor of HomeController. In ASP.NET MVC controllers are built by a controller factory which by default is the DefaultControllerFactory class which simply invokes the default constructor.
The fact that you are getting a NullReferenceException instead of the class HomeController doesn't have a default constructor indicates that you have setup a custom controller factory in your Global.asax which is supposed to provide instances of your controllers but this custom controller factory doesn't passes null to the HomeController constructor, so when later you try to access this service _profileService.GetProfile() you get the exception. You are probably using some dependency injection framework and in your Application_Start you have something like this:
ControllerBuilder.Current.SetControllerFactory(new SomeCustomControllerFactory());
So if you are using a DI framework you need to setup this framework to pass a specific implementation of the IProfileService interface to the constructor. How this is done would totally depend on the framework you are using.

MVC3 Controller constructor + Ninject

I'm at the moment working on a MVC3 Web application and ecountered a new problem with Ninject.
I'm using the following code in my controller:
public class TestController : Controller
{
public IRepository<CustomerModel> rep;
public TestController(IRepository<CustomerModel> repository)
{
this.rep = repository;
}
public ActionResult Index()
{
return View();
}
}
And my Ninject Module:
public class RepositoryModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRepository<>)).To(typeof(Repository<>));
}
}
However this just throws me "System.MissingMethodException: No parameterless constructor defined for this object." when I try to render the Index view.
If I then add:
public TestController() : this(new Repository<CustomerModel>(new XenCRMEntities())) { }
so my actually TestController looks like:
public class TestController : Controller
{
public IRepository<CustomerModel> rep;
public TestController() : this(new Repository<CustomerModel>(new XenCRMEntities())) { }
public TestController(IRepository<CustomerModel> repository)
{
this.rep = repository;
}
public ActionResult Index()
{
return View();
}
}
It works, but as you can see the new constructor pretty much break the whole point of IoC.
How do I fix this?
Thanks in advance.
A short test showed that there is not problem with generic bindings in the MVC3 extension. I guess that the problem is not in the Controller but that the Repository can not be created because it has some unknown dependencies.
But this brought me to change the dependency resolver a bit to show the Ninject stacktrace whenever the requested type can be resolved but one of its dependencies fails to be resolved. Update to the latest version on the build server to get a better stack trace.
You will need to change the controller factory, as the regular MVC controller factory does not do DI.
You can look here for more information on how to setup MVC + Ninject: MVC3 + Ninject - How to?
It turns out that its not the Controller thats messing it up, but that Ninject dont Bind my generic Repository and IRepository correctly - I have therefore created a new post: Ninject + Bind generic repository
Don't use this binding!!!
Bind(typeof(IRepository<>)).To(typeof(Repository<>));
I changed my code use this binding and server was crashed, it works for one user but for thousands requests it's really bad
Use
Bind(typeof(IRepository<IClass>)).To(typeof(Repository<Class>))

ASP.MVC and mvccontrib fluent test with IOC

I am trying to use the fluent test helpers to test an AbstractRestfulFluentController
public class CustomerController : AbstractRestfulFluentController
{
private readonly IService<Customer> _customerService;
private readonly IService<CustomerAddress> _addressService;
public CustomerController(IService<Customer> customerService, IService<CustomerAddress> addressService)
{
//Assume we use these in other actions
_customerService = customerService;
_addressService = addressService;
}
public ActionResult Index()
{
return View();
}
}
As you can see I am injecting some services into the controller and resolving them using IOC. My problem is that all the examples I have found using the fluent test methods in mvccontrib don't work without a paramaterless controller.
public void SuccessfulIndex()
{
GivenController.As<CustomerController>()
.ShouldRenderItself(RestfulAction.Index)
.WhenCalling(x => x.Index());
}
I'm not sure what I need to do in order to be able to use IOC with the fluent test techniques in mvccontrib. I have found a few comments that it is possible but haven't found anything. What can I do in order to actually use IOC and fluent tests?
You could write a method which allows you to provide the instance of the controller:
public static class GivenController
{
public static ActionExpectations<T> As<T>(T controller) where T: Controller, new()
{
return new ActionExpectations<T> { MockController = controller };
}
}
And then in your unit test:
var controller = CreateMockedCustomerController();
GivenController
.As<CustomerController>(controller)
.ShouldRenderItself(RestfulAction.Index)
.WhenCalling(x => x.Index());
The requirement is that the controller should be a mock object which in my opinion is not a very clean approach (testing a mocked object). You could create it like this:
var controller = MockRepository
.GeneratePartialMock<CustomerController>(new object[] { dep1, dep2 });
Notice how dependencies are passed to the constructor.
Have you tried property injection instead of constructor injection?
http://ninject.codeplex.com/wikipage?title=Injection%20Patterns
I am currently having a weird ninject issue that I just posted about, but this should at least point you in the right direction...all the code is there for setting up the dependency injection.
https://stackoverflow.com/questions/3909452/unit-testing-asp-net-mvc-controllers-with-ninject

Categories