Following the ASP.Net 5 Getting Started document I see that because of dependency injection at the top of any controller that will access the database I need to put something like
private DbContext _Context;
public HomeController(DbContext Context)
{
_Context = Context;
}
to inject the DbContext into the controller for use. In my ASP.Net 5 MVC 6 Web App every single page will be interacting with the database so I thought I would create a BaseController that the reset of my controllers would inherit from and put the injection code there. I have done this but every controller that inherits from the BaseController give me the error
There is no argument given that corresponds to the required formal parameter 'Context' of 'BaseController.BaseController(DbContext)
I am new to DI and not sure if I am doing things right or even if it can be done the way I want to. Is it possible to do it this way or do I have to put that code on every controller I make, and if I do have to do that how can I write an action in the BaseController that interacts with the DB?
If your base controller has a constructor that takes DbContext then any controller that inherits it must also use the same constructor like this so it can pass the dependency to the base class:
public HomeController(DbContext Context):base(Context)
{
}
Related
I've setup Unity in Bootstrapper.cs of my MVC application, all is working well for constructor injection on my controllers...
My question is when I'm in an ActionResult within a controller I need to get a reference to the container I previously created in Bootstrapper.cs so I can use it to resolve classes for me.
e.g:
public ActionResult Index()
{
//-- container needs a reference to unity container
var testService = container.Resolve<ITestService>();
return View(testService);
}
I need to get a reference to the container
No you don't. You should never need to reference the container (or the DependencyResolver) from within your application.
Use constructor injection instead:
public class HomeController : Controller
{
private readonly ITestService testService;
// constructor
public HomeController(ITestService testService)
{
this.testService = testService;
}
public ActionResult Index()
{
return View(this.testService);
}
}
Since you are using the MVC3 integration package for unity, you probably registered a Unity specific DependencyResolver in the startup path of your application. That looks much like this:
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
When you've done this, your custom DependencyResolver will delegate the creation of controllers to the Unity container and the Unity container is able to inject depdencies of the constructor's of the controllers.
The next thing you should never do is letting views do any work and making them dependent on your services. Views should be dumb and do nothing more than map the data they get from the controller and transform them to HTML (or JSON or whatever).
In other words, do not pass on the testService to the view. Calling the testService from within the view hides that logic, makes the view more complicated, and makes the system hard to test. Since you're using an ITestService abstraction, I assume you want to be able to test your code, but testing the view is not easy (or at least, not as easy as you can test the controller).
What you should do is let the controller call the testService and gather the data that is needed for the view to use. Than pass on that data (perhaps combined in a single class, a view model) to the view.
I have a HomeController and a Referrence of a type-class.If I create a new object of the class it works fine for me. But I dont want to create new object in the Controller instead I want to pass a referrence of the class through the HomwController's Constructor.Here is my code. I need to implement DI here.
//private readonly UnitOfWork<Student> _unitOfWork = new UnitOfWork<Student>();
private readonly UnitOfWork<Student> _unitOfWork;
//TODO ??
public HomeController(UnitOfWork<Student> unitOfWork)
{
_unitOfWork = unitOfWork;
}
public ActionResult Index()
{
return View(_unitOfWork.GenericRepository.GetAll());
}
Any help?
First, if you want to use dependency injection, you'll have to go through a third party dependency injection container - NInject or Unity for example among many others (or building your own if you are looking for some challenge).
Second, your HomeController should take an abstract unit of work type (interface or abstract class) as a parameter. You are actually using a concrete type in your HomeController constructor which is not how things should work in a dependency injection world (when using "Constructor Injection", your dependency container is in charge of providing the concrete implementation for the abstraction, based on container configuration).
Third your UnitOfWork<Student> does not make a lot of sense. A Repository<Student> would make some sense, but a Unit Of Work is not working on a single "Type" but rather on a "collection" of different data sets (a unit of work is potentially working on a collection of repositories). What would make sense here is to specify a parameter IUnitOfWork unitOfWork in your HomeController constructor, and configure your depency container to pass in a concrete UnitOfWork object on which you can get your Repository<Student> do operations on it in your action method (and potentially on other repositories accessed from the UnitOfWork object) and then Commit all modifcations by calling the associated method on the UnitOfWork object.
You should make some searches arround NInject use with ASP.NET MVC3 and also take a look at EntityFramework if you are dealing with UnitOfWork and Repository patterns (and if data is backed by a DB).
EDIT
In reaction to your comment dealing with (IUnitOfWork<Student> and IUnitOfWork<Course>).
As I said before, it does not make a lot of sense :
A UnitOfWork can be grossly seen as a "container" of repositories, giving access to these repositories and coordinating actions (like commiting all the changes) on these repositories. You should rather have an abstract non generic type IUnitOfWork, providing access to generic repositories such as IRepository<Student> or IRepository<Course>, and also containing a Commit method which would commit to DB (or file, or memory or whatever the unitofwork/repository implementation is targeting to persist data).
This way instead of injecting an IRepository<Student> and/or IRepository<Course> in your controller constructor (or if your controller needs to work on 10 different repositories, well, pass 10 parameters :S), you just accept a single parameter of abstract type IUnitOfWork (the concrete instance being injected by the DI container), and then any action method can work on any set of repository by getting them from the UnitOfWork, and once it has done all the changes, it can call Commit on the unitOfWork which will take care of comming all the modifications that have been done in the repository.
That's the theory and the general idea.
Now more specifically about DI in ASP.NET MVC, the more common way (there are other ways) of "plumbing" the DI container is to create a class inheriting from IDependencyResolver making use of the DI container to resolve types, and in Application_Start call DependencyResolver.SetResolver whith an instance of this class.
This way, when ASP.NET MVC is asked to create a controller (end user request), it will go through this depency resolver to ask for an instance of the controller, and this dependency resolver will turn to the DI container to create an instance of the controller by taking care of all needed injection.
You should take a look on the website / forums of your specific DI container as they all show ways to plumb it with ASP.NET MVC.
This is just a very high overview, there are a lot of tricky details, but that's the gross idea.
EDIT2
Just posted an article (my first one) on my blog to explain how to correctly use the Repository and UnitOfWork patterns in an ASP.NET MVC project.
http://codefizzle.wordpress.com/2012/07/26/correct-use-of-repository-and-unit-of-work-patterns-in-asp-net-mvc/
Are you talking ASP.NET MVC ?
I have been working with Ninject for some time now, and am very happy with it! Take a look at the sample app in this repository to get an idea on how to use it in ASP.NET MVC 3:
https://github.com/ninject/ninject.web.mvc/tree/master/mvc3
To expand a bit on the reply, here's a code snippet from where I set up the Ninject bindings
kernel.Bind(typeof(IUnitOfWork<>).To(typeof(UnitOfWork<>));
And my controller:
public class MyController : Controller {
private readonly IUnitOfWork<Student> uowStudent;
public MyController(IUnitOfWork<Student> uowStudent) {
this.uowStudent = uowStudent;
}
}
Then all you need to do, is make sure any arguments in the constructor for the UnitOfWork class are also bound in the kernel.
I'm new to Rhino, and wondered how to mock a local variable/object inside a method of a class I'd also be mocking. In this case I'd be doing it with an ASP.Net MVC controller & action method.
Here's what the controller looks like, simplified:
public class HomeController : Controller {
public myObjectType myMockedObject; //I want to mock this
public myNonMockedObject; //don't want to mock this
public ViewResult Index() {
//call various methods on the mocked and nonmocked members
return View();
}
}
In other words, I'd like to create a mock home controller and mock some local variables within it and their methods-- but not all of them. Is this possible using Rhino?
You can inject these through constructor parameters. Just write constructor that takes myObjectType as parameter. Within this constructor just initialize your fields.
Note1: in case to run MVC, you will need also parameterless ctro, or modify ConstructorFactory (e.g. here https://www.codeproject.com/Articles/560798/ASP-NET-MVC-Controller-Dependency-Injection-for-Be). Or just think about using some IoC container (e.g. https://www.nuget.org/packages/Unity/) that can inject whatever you want inside the controller (mock or normal class).
Note2: you should extract an interface from myObjectType class and mock that interface instead of concrete class (Rhino handles that better).
Note3: I am usually trying to put all the logic (and test that separately) outside of controller since it is quite tough to test the controller (you need to initialize a lot of stuff there what involves another mocking).
I'd like to use a class extending Controller as the default base type for controllers in my project, as opposed to using Controller itself. So, I would be doing this:
public class FooController : MyBaseController
Is there a way I can enforce this, so that people cannot create controllers which extend Controller directly?
You can always create a unit test that (via reflection) retrieves all classes that derive from Controller and asserts that each class is also a subclass of MyBaseController. It would be along the lines of
[TestMethod]
public class All_Controllers_Derive_From_MyBaseController()
{
// Act
var controllerTypes = AppDomain.CurrentDomain
.GetAssemblies()
.SelectMany(asm => asm.GetTypes())
.Where(t => t.IsSubclassOf(typeof(Controller))
.ToList();
// Verify
foreach (var type in controllerTypes)
{
// Make sure the type isn't the actual controller type
if (type is Controller)
continue;
Assert.IsTrue(type.IsSubclassOf(typeof(MyBaseController)),
string.Format("{0} is not a subclass of the MyBaseController class", type.FullName));
}
}
Now if someone creates a controller that doesn't use your base controller your unit tests will fail and tell you which ones are not correct.
Note that this code was written free-hand, so it might need some adjustment but that's the basic idea.
However I prefer the unit testing approach above here is another one by using a custom controller factory.
public class MyControllerFactory<T> : DefaultControllerFactory where T : Controller
{
#region Overrides of DefaultControllerFactory
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (!typeof(T).IsAssignableFrom(controllerType))
{
throw new NotSupportedException();
}
return base.GetControllerInstance(requestContext, controllerType);
}
#endregion
}
You can set it up in the application start method of your Global.asax like this:
ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory<MyBaseController>());
This of course causes a runtime exception when not deriving from MyBaseController which may not be suitable in your current scenario.
You have two choices and both involve writing some code.
choice #1 You can create a filter and try and catch the error at runtime. You better have good a good user acceptance test process in place to touch all of the pages.
Choice #2 involves writing a task for MSBuild that checks that each controller class is derived from your specified class. Just load the application assembly (or assemblies) and go to town!
I prefer choice #2. It doesn't affect application runtime performance and gives you better coverage. You can run it at the end of a build.
http://msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx
http://msdn.microsoft.com/en-us/library/t9883dzc.aspx
I want to question your reasons, but here's an answer: One (slightly underhanded) method you could use is to name the base class "Controller" and put it in the same namespace as your individual controllers. As long as people don't specifically extend System.Web.Mvc.Controller, they'll get your Controller class. None the wiser, possibly.
You could modify the default code generation template, so that it always creates a new controller that inherits from the correct class. The downside is this involves distributing the updated templates to the dev team. See Scott Hanselman's blog for more detailed instructions.
http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspx
I have begun using Castle Windsor and somehow my app is all up and running but I dont really understand how its working. Don't refer me to the documentation as I wouldn't be here otherwise.
In my Global.asax.cs I have this:
private static IWindsorContainer container;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
BootstrapContainer();
}
protected void Application_End()
{
container.Dispose();
}
private static void BootstrapContainer()
{
container = new WindsorContainer()
.Install(FromAssembly.This());
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
Now this is registering a new controller factory which I understand. The installation of a WindsorContainer from the current assembly I think registers all installers for example I have a repository installer. I assume that the container that is created in Global.asax is passed to the installers.
public class RepositoriesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromThisAssembly()
.Where(type => type.Name.EndsWith("Repository"))
.WithService.DefaultInterface()
.Configure(c => c.LifeStyle.PerWebRequest));
}
}
In my controller I have created a constructor and passed in a IRepository argument. What I dont understand is how the controller accepts this argument.
Secondly as a test I created 2 repository classes that implement a IRepository. Putting a breakpoint in the controller constructor it passes in one of these classes. How do I map what class that implements IRepository should be passed to the constructor?
I also have Fluent NHibernate up and running. For the next stage I would like the IRepository to have a dependency on the ISession. How do I do that?
Thanks for your help
Since you have registered a controller factory that uses Windsor, it is the Windsor IoC container that is responsible for resolving all your controller instances as and when they are needed.
That is, when you access a URL in your MVC project that points to the action "Index" on your "HomeController" your WindsorControllerFactory will be asked, by the MVC framework, for an instance of HomeController.
If that controller has a constructor which takes an instance of IRepository and you have registered IRepository as a service with the container then Windsor will know how to satisfy the dependency of the HomeController class. Therefore it can first resolve IRepository into some concrete class, instantiate this, and pass it in as a parameter to the HomeController constructor before returning the instance of HomeController to the MVC framework.
If you need different implementations of IRepository for different purposes (i.e. a UserRepository and a ProductRepository) you could create separate interfaces for these, each of which extend IRepository, e.g.:
public interface IProfileRepository : IRepository {}
Then you can use Windsor's fluent registration API to register all concrete classes that implement IRepository, and have them registered by the specific service they provide, e.g. IProfileRepository.
If you do this, Windsor will automatically resolve all instances that implement IRepository for you without you having to write any new registration code when you add a new implementation.
As for making your repository classes depend on ISession, you can do this in a number of ways. I would recommend not letting them depend directly on a session, but rather let them depend on a class through which they can obtain the current session (so that you can share sessions between repositories). There's lots of information on why this is good practice out there on the web, just do a search.
Now, as for actually making it happen, you can either:
Register an instance of a class (by interface) that will retrieve a session for you with Windsor and let Windsor resolve this class as a parameter to your repository constructors.
Register ISession with Windsor and use a factory method to retrieve it when it is resolved.