How do I Access the RequestContext Outside the Controller? - asp.net-mvc

Background
I am trying to move business logic out from the controllers into their own services.
Controller
public class AccountController : Controller
{
private readonly IAccountService _accountService;
public AccountController(IAccountService accountService)
{
_accountService = accountService;
}
....
}
I'm using Unity to inject dependencies. I'd like to use the Url.GenerateUrl() helper method within the implementation of IAccountService but Url is a property against the controller.
I looked at the MVC source to see how this is done but it requires me to access the RequestContext from outside of the controller, and I don't know how to do that.
Question
How do I access the RequestContext from outside the controller? If that won't solve my problem, how do I solve the problem given my setup?

This might not be quite right because I'm unable to test it at the moment, but I think that you can do something like this in .NET 4+:
using System.Web;
using System.Web.Mvc;
// ...
var helper = new UrlHelper(HttpContext.Current.Request.RequestContext);
string url = helper.GenerateUrl(/* ... */);
It might make more sense to pass the context from the controller to your IAccountService implementation rather than grabbing it directly from HttpContext.Current.

However i'd like to use the Url.GenerateUrl helper methods within my implementation of IAccountService
Simply pass this information as parameter. Example:
public ActionResult Index()
{
var someUrl = Url.Action("about");
_accountService.Foo(someUrl);
}
Now you no longer need UrlHelper inside your service classes. Everything that needs interacting with MVC infrastructure shouldn't be placed in your service classes. They shouldn't depend on any Request, Response, Session, ... It's the controller's responsibility to work with those objects and glue them together with your service classes.

Related

mvc api controller dependency injection System.Web.Http and System.Web.Mvc reference error

I am doing an MVC 5 with API2 Controller Application.
I have a Controller that call an ApiController in the same project.
In my Api Controller Method I want to use DI.
It looks like this.
[ActionName("Method1")]
[HttpPost]
public int Method1(long User_id)
{
long user_id = Newtonsoft.Json.JsonConvert.DeserializeObject<long>(User_id.ToString());
IContactRepository _contactRepository = DependencyResolver.Current.GetService<IContactRepository>();
return _contactRepository.Get_CountMensajeByUser(user_id);
}
In order to use
[ActionName("RetProduct")] and [HttpPost]
I have to include using System.Web.Http; reference
But, in the other hand, in order to use DependencyResolver I have to include
using System.Web.Mvc;
when I include that reference, System.Web.Http; does not work.
Another alternative is to set de DI in the API Controller Constructor like this
private IContactRepository _sessionRepository;
public ApiController(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
So i avoid to use DependencyResolver. But I have to use Parameters in the Controller Constructor.
On my controller where I call Api controller like this.
var webApi = new APIController();
model.CantMensajeByUser = webApi.CountMensajeByUser(10);
Where I am not using parameters.
What is the correct way to do it?
I think an easier solution for the problem you are trying to solve is to use an actual IoC container. For C#.NET in particular, Ninject is very easy to use and the best part is that you can resolve all of your dependencies in one file rather than doing that inside of your business logic.
I encourage you to check out http://www.ninject.org/.

Dependency injection with Global.asax

I am using dependency injection for the inject interface with the classes
I use it in the Global.asax like this
new UnityContainer().RegisterType<IBookingService, BookingService>()
and controller
IBookingService bookingService
Now the thing is I want to change the injected implementation class for an interface in the controller level
How can I do it with a controller level?
i want to do some things like this in controller level
private readonly IBookingService bookingService;
if(countryCode = SE ){
bookingService = new bookingSE();
}
else IF (countryCode = NO ){
bookingService = new bookingNO();
}
i want to use Dependency injection for this
Make sure that you use the Unity.Mvc NuGet package. This will add a App_Start\UnityConfig.cs file to your project and you can add the registrations in its RegisterTypes method as follows:
container.RegisterType<IBookingService, BookingService>();
Perhaps you are already doing this, but I wanted to make sure since your exact code example with the new UnityContainer().RegisterType will not work.
Another interesting thing that this package does can be viewed in the App_Start\UnityWebActivator.cs file:
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
This line will register the unity container as standard MVC DependencyResolver. This allows constructor injection to be applied to your controllers. With this you can define your controller as follows:
public class MyCoolController : Controller
{
private readonly IBookingService bookingService;
public MyCoolController(IBookingService bookingService)
{
this.bookingService = bookingService
}
public ActionResult Index()
{
// your usual MVC stuff here.
}
}
In almost all cases, the use of constructor injection is advised over all forms of injection so stick with constructor injection unless there is no other way. And if you think there's no other way, please to ask here at Stackoverflow. We might be able to give some feedback on your code and design.
Just call Resolve
var bookingService= container.Resolve<IBookingService>()

unity.mvc4: how to get a reference

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.

How grails has implemented handler mappings?

I have been trying to mock grails' convention over configuration paradigm in a spring mvc application and i am finding it difficult to automate handler mappings.
Basically i have a controller like this.
#Controller
#RequestMapping(value = {"/", "/contact"})
public class ContactController {
#Autowired
private ContactService contactService;
#RequestMapping(value = {"/","/index"})
public String listContacts(Map<String, Object> map){
map.put("contact", new Contact());
map.put("contactList", contactService.listContact());
return "contact";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addContact(#ModelAttribute("contact")Contact contact, BindingResult result){
contactService.addContact(contact);
return "redirect:/contact/index";
}
#RequestMapping(value = "/delete/{contactId}", method = RequestMethod.GET)
public String removeContact(#PathVariable("contactId")Long contactId){
contactService.removeContact(contactId);
return "redirect:/contact/index";
}
}
Now, i have tried "ControllerClassNameHandlerMapping", but it seems to have a limitation with three part url.
I basically want all the requests to be automatically mapped to the appropriate controller and actions, without using #RequestMapping
Any pointers will be great help
That won't be easy. Grails framework has written bunch of ASTTransformers where they inject annotations and other properties in to the class which is controller. Take a look at the source code for grails-plugin-controllers and you cans see the code under compiler.web and see what they are doing. Also if you take a look at ControllersGrailsPlugin you will see that its watching the directory grails-app under the parent folder. It won't be that easy to do. Hope this helps
UPDATE
Making AST transformations via ASM in your case, is probably the fastest way, maybe post-compilation step?
Hope it helps
It won't be that simple but what you want is likely to perform the following :
Write an annotation processor(scan classpath from classloader) to collect Controllers annotations and matching class
Hook into Spring mvc API to inject the Request Mapping based on your conventions.
Then you would also need to collect the method parameters to auto-inject pathVariables, etc.
If Spring MVC is not expecting to play with the RequestMapping annotation as soon as the Controller annotation is found (or defaults to something), then you're good to go (Post Bean Definition processors or similar mechanisms)...
Not that simple, but definitely possible...

Partially mocking an ASP.Net MVC action method in Rhino Mock?

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).

Resources