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.
Related
Account Controller does not Register correctly
I have an ASP.NET MVC application with Individual user accounts using Identity. In my account controller I have a UserMappingService that I would like to inject.
There are two AccountController constructors, the one that was originally an empty constructor is the one that is causing issues. I need to inject the UserMappingService here. Before I added the Service to the parameters of the constructor I was able to make the controller register the empty constructor by adding this to the UnityConfig.cs
//parameterless constructor in AccountController.cs
public AccountController()
{
}
// From UnityConfig.cs in RegisterTypes method
container.RegisterType<AccountController>(new InjectionConstructor());
The problem is that once I add the service as a parameter, I get errors.
private IUserMappingService userMappingService;
//constructor with interface in the parameter AccountController.cs
public AccountController(IUserMappingService mappingService)
{
userMappingService = mappingService;
}
//From UnityConfig.cs
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IUserMappingService, UserMappingService>();
container.RegisterType<AccountController>(new InjectionConstructor());
}
Resulting error upon runtime is:
Error in RegisterType(Invoke.Constructor())
ArgumentException: No member matching data has been found.
I am pretty sure the (InjectionConstructor) is only good for for the default parameterless constructor, but I don't know how else to Register the controller in this case.
You can spec the dependency type like this:
var ctr = new InjectionConstructor(typeof(IUserMappingService));
container.RegisterType<AccountController>(ctr);
Or you can flag your constructor with InjectionConstructorAttribute:
[InjectionConstructor]
public AccountController(IUserMappingService mappingService)
{
userMappingService = mappingService;
}
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.
I'm having trouble with Autofac constructor injection. I'm somewhat solved my problem but I'm turning to the community for a full solution.
This works with DI
builder.RegisterControllers(typeof(MvcApplication).Assembly)
.InstancePerHttpRequest();
This does not.
builder.RegisterControllers(typeof(MvcApplication).Assembly)
.AsImplementedInterfaces()
.InstancePerHttpRequest();
Here's my controller.
public class HomeController : BaseController
{
public HomeController(IPlugin plugin)
{
}
}
I have a module to resolve the IPlugin injection. I'm wondering why I need to take the .AsImplementedInterfaces() out to make this work. I would prefer to use interfaces because I'm using MEF to import IControllers from other assemblies at runtime.
Update
Thanks to japonex (see comments below) I've updated my solution. Here's what I did to get everything working.
First my project has its own controllers, and I then use MEF to import controllers from other assemblies.
Controllers for my current project must be registered without the .AsImplementedInterfaces() call, so like so
builder.RegisterControllers(typeof(MvcApplication).Assembly).InstancePerRequest();
This will put the controllers into Autofac using the type instead of as an interface (MyProject.Controllers.HomeController instead of System.Web.Mvc.IController).
Next in my plugin project I simply had to export the types instead of as an interface.
So I use this
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : PluginController
Instead of this
[Export(typeof(IController))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : PluginController
Notice the difference in the Export attribute.
Next I set the current DependencyResolver to the AutofacDependencyResolver.
Last, but not least, I created a custom ControllerFactory to create the controllers. Technically this isn't needed, since I'm no longer using interfaces, but I have code to check the status of the controller before creating it. This allows me to easily enable/disable a plugin from an admin area.
So the root of the problem is that Autofac needed types instead of interfaces to resolve properly. I'm sure this could be done with interfaces, but this solution works for me. The only real reason I would have wanted to use interfaces is because I could then ask for all controllers from Autofac without knowing their type.
public class MyControllerFactory : DefaultControllerFactory
{
private readonly IContainer _container;
public PortalControllerFactory(IContainer container)
{
_container = container;
}
public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
Type controllerType = GetControllerType(requestContext, controllerName);
if(controllerType == null)
{
throw new HttpException(404, ErrorMessages.Http404);
}
IPlugin plugin = PluginManager.Current.GetPlugin(controllerType);
if (plugin != null && plugin.Status != Common.Enums.PluginStatus.Enabled)
{
//the controller/plugin is disabled so modify the route data and return the controller
RouteData data = new RouteData();
data.Values.Add("controller", "plugin");
data.Values.Add("action", "disabled");
data.Values.Add("plugin", plugin.Name);
requestContext.RouteData = data;
return ViewRenderer.CreateController<Project.Controllers.PluginController>(data);
}
var controller = ((AutofacDependencyResolver)DependencyResolver.Current).RequestLifetimeScope.Resolve(controllerType);
return controller as IController;
}
}
When you use .AsImplementedInterfaces you're saying that for each concrete type, Autofac registers this type for each interface implementation.
So, you're registering all controllers in your Assembly to IController and propably because you don't have any rule (keyed or named registration) to decide which concrete type return, Autofac probably returns the last registration for IController.
Try call container.Resolve and see what you get.
Consider that if you have:
public class HomeController : BaseController
{
public HomeController(IPlugin plugin)
{
}
}
and
public class Home2Controller : BaseController
{
public Home2Controller(IPlugin plugin)
{
}
}
HomeController will be registered to IController and the
Home2Controller also will be registered to IController.
And I think the default behavior of Autofac is to use the last registration if you don't use any kind of rule (keyed or named registration)
I am creating a new project in ASP.net using MVC 4.
I want to setup dependency injection using Ninject. But before I proceed what are the best practices when setting up dependency injection?
Currently I have a binder class setup within the webproject which will reference data projects within the solution.
The binder class is as shown below:
Public static class Binder
{
static Ninject.IKernel _kernel;
static Binder()
{
_kernel = new Ninject.StandardKernel();
_kernel.Bind<IConfig>().To<AppSettingsConfig>();
_kernel.Bind<IDocuments>().To<DocumentsClass.Documents>();
}
public static T GetImplementation<T>()
{
return _kernel.Get<T>();
}
}
Then within my controller i use the GetImplementation method to use the exact require dependency rather than registering all on application startup.
Example code from controller:
Public ActionResult Get (int id)
{
var repository = Binder.GetImplementation<IDocuments>();
// do some stuff with the repository here
}
Not sure if this would be a good approach? Any advice would be good.
What you have now is an example of the Service Locator anti-pattern. Google for more details as it has been discussed many times.
In short, rather than relying on the service locator
public class SomeController
{
public ActionResult Get (int id)
{
var repository = Binder.GetImplementation<IDocuments>();
// do some stuff with the repository here
}
}
you should have your service injected into the client class (rely on constructor injection)
public class SomeController
{
private IDocuments documentService { get; set; }
public SomeController( IDocuments documentService )
{
this.documentService = documentService;
}
public ActionResult Get (int id)
{
var repository = documentService;
// do some stuff with the repository here
}
}
In this specific case, you could set up your controller factory to use your IoC container to resolve your controllers.
Best practice for Ninject is to use the MVC extension for Ninject: https://github.com/ninject/ninject.web.mvc/wiki/MVC3
You are linked to the instance of your Binder class inside controller. It makes your class not reusable and it must be refactored, because it is not resposibility of controller to get correct instance of IDocuments implementation.
There is must be some external dependency resolver(like example - Ninject) which have to make constructor injection or property injection.
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>))