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
Related
So I have created the simplest of the applications using ASP.NET MVC (in .NET Framework) and I want to demo dependency injection to a junior using this. it is very simple code, even a newbie can understand it.
public interface IMovieRepository
{
MyViewModel GetDetails(string movie);
}
public class MoviesController : Controller
{
[HttpPost]
public async Task<ActionResult> Search(string movie)
{
// Confusion here! Is the below line a good place to inject dependency
IMovieRepository repository = new DBMovieRepository(); // <-- it can be DBMovieRepository or WebServiceMovieRepository or MockMovieRepository
MovieFinder finder = new MovieFinder(repository);
MyViewModel model = await finder.Find(movie);
return View(model);
}
}
public class MovieFinder
{
private IMovieRepository _repository;
public MovieFinder(IMovieRepository repository)
{
_repository = repository;
}
public async Task<MyViewModel> Find(string movie)
{
// Connect to database and return a detailed object
var myViewModelObj = _repository.GetDetails(movie);
return myViewModelObj;
}
}
public class DBMovieRepository : IMovieRepository
{
public MyViewModel GetDetails()
{
// Code for fetching data from a database
}
}
public class WebServiceMovieRepository : IMovieRepository
{
public MyViewModel GetDetails()
{
// Code for fetching data from a IMDB webservice
}
}
public class MockMovieRepository : IMovieRepository
{
public MyViewModel GetDetails()
{
// Code for returning a mock object here
}
}
There is an inline comment in the code where I asked that my confusion is here. Is that a good place to inject dependencies or do I have to inject it in the MoviesController constructor. If yes, then how will I pass it to the constructor? This is a .NET Framework 4.5 application and I don't want to complicate the lesson by introducing a DI Container and just want to use Pure DI to clarify the concept to my junior.
This is a .NET Framework 4.5 application and I don't want to complicate the lesson by introducing a DI Container and just want to use Pure DI to clarify the concept to my junior.
That literally doesn't make sense.
Pure DI
Or Dependency Injection simply means using IOC to provide an Instance of a Dependency to the object (via Constructor or Property).
Inversion of Control simply means that instead of the dependent object creating the Dependency, you invert control to something else to provide the instance.
You can Architect your Controller to use IOC. You can't DI without something providing the instance. The most lightweight/semi-hacky way to write your DI with minimum effort using your stack is to write your own Controller Factory to inspect your constructor for its dependencies and inject whatever those dependencies are (or just assume what it needs, pass it... yikes).
Relevant SO Question of Mine: My MVC Custom ControllerFactory works but could it be better?
I've used DI purely for tests within a controller and I'm oddly having a real hard time using it outside of a controller. I had a static caching class called caching engine, but apparently DI and static classes don't mix well, so I decided to make it non-static instead. However, I can't get this to work well and I'm not sure what the best approach is. I have a controller that I need to pass products and send them to the view. However, for speed improvements, I'd like to use memory caching, but I'm really confused on the best design here. I'd like to know the best way to do this.
1) How does instantiating a new class work with DI if you don't pass the dependencies?
2) Should I inject my memorycache and product repository into the controller and then pass them into the cachingengine constructor? That seems like a lot of unnecessary parameter passing, so I didn't like this.
3) Should I just instantiate a MemoryCache class in the caching engine and not worry about DI?
4) Should I just switch the CachingEngine back to a static class?
Thank you for your help and advice. It is much appreciated.
Here's the Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//Add Dependencies
services.AddTransient<IProductRepository, ProductRepository>();
//Extention method that sets up the shared objects used in MVC apps
services.AddMvc();
services.AddMemoryCache();
....
}
}
Here's the Controller
public class MainController : Controller
{
private CachingEngine engine;
public MainController()
{
//This isn't valid, missing parameters
engine = new CachingEngine();
}
public IActionResult Index()
{
var products = CachingEngine.GetProducts();
....
}
}
And here's the caching class:
public class CachingEngine
{
private readonly IMemoryCache memoryCache;
private IProductRepository prodRepo;
public CachingEngine(IMemoryCache memory, IProductRepository rep)
{
memoryCache = memoryCache;
prodRepo = rep;
}
public List<Product> GetProducts()
{
var cacheKey = "Products";
List<Product> prods;
if (memoryCache.TryGetValue(cacheKey, out prods))
{
return prods;
}
else
{
memoryCache.Set(cacheKey, prodRepo.Products);
return prods;
}
}
}
First off, to clarify, a static class cannot be instantiated so how could you inject instantiations into its constructor using a dependency injection framework. It is not that static classes do not work well with DI, they do not work at all and make no sense in the context of dependency injection.
Your Controller needs a CachingEngine, so you need to inject it, a simple rule of setting up DI in your software: do not use the new operator.
Anytime you use the new operator you are tightly coupling your code to a particular type and you have the exact problem that Dependency Inject is trying to solve.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//Add Dependencies
services.AddTransient<IProductRepository, ProductRepository>();
//configure DI for IMemoryCache and CachingEngine
services.AddTransient<IMemoryCache, MyMemoryCacheClass>();
services.AddTransient<MyICachingEngineInterface, CachingEngine>();
//Extention method that sets up the shared objects used in MVC apps
services.AddMvc();
services.AddMemoryCache();
....
}
}
public class MainController : Controller
{
private readonly MyICachingEngineInterface _cachingEngine;
public MainController(MyICachingEngineInterface cachingEngine)
{
_cachingEngine = cachingEngine;
}
public IActionResult Index()
{
var products = _cachingEngine.GetProducts();
....
}
}
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 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 relatively new to testing and MVC and came across a sticking point today. I’m attempting to test an action method that has a dependency on HttpContext.Current.Cache and wanted to know the best practice for achieving the “low coupling” to allow for easy testing. Here's what I've got so far...
public class CacheHandler : ICacheHandler
{
public IList<Section3ListItem> StateList
{
get { return (List<Section3ListItem>)HttpContext.Current.Cache["StateList"]; }
set { HttpContext.Current.Cache["StateList"] = value; }
}
...
I then access it like such... I'm using Castle for my IoC.
public class ProfileController : ControllerBase
{
private readonly ISection3Repository _repository;
private readonly ICacheHandler _cache;
public ProfileController(ISection3Repository repository, ICacheHandler cacheHandler)
{
_repository = repository;
_cache = cacheHandler;
}
[UserIdFilter]
public ActionResult PersonalInfo(Guid userId)
{
if (_cache.StateList == null)
_cache.StateList = _repository.GetLookupValues((int)ELookupKey.States).ToList();
...
Then in my unit tests I am able to mock up ICacheHandler.
Would this be considered a 'best practice' and does anyone have any suggestions for other approaches?
The recommended approach is to stub HttpContextBase. Its documentation states
When you perform unit testing, you
typically use a derived class to
implement members with customized
behavior that fulfills the scenario
you are testing.
This is mostly covered for TypeMock here.
var httpContext = MockRepository.GenerateStub<HttpContextBase>();
httpContext.Stub(x=>x.Cache).Return(yourFakeCacheHere);
var controllerContext = new ControllerContext(httpContext, ....);
var controller = new HomeController();
controller.ControllerContext = controllerContext;
You are hiding a specific, hard-to-test API (HttpContext.Current) behind and interface and using Constructor Injection to inject the dependency into the consumer. That's more or less textbook DI (I would add Guard Clauses in the constructor, though).
If you create a new ASP.NET MVC project in Visual Studio, you will see that in the AccountController.cs file, a very similar thing is being done to hide the MembershipProvider.