Using IoC in extension methods - asp.net-mvc

I am working on an ASP MVC 3 app and I'm writing a custom html helper. It's nothing special or hugely complex, but it will need an instance of an interface from structure map. I know I can simply call into structuremaps' object factory from inside the method, but since the rest of the app uses IoC rather than service location I'd like to keep it that way.
Is there a way to inject interfaces into extension methods from inside and asp net mvc app?
UPDATE
An example of what I'm doing might help:
public static class ShowUrl
{
public static string ForShow(this UrlHelper url, int showId)
{
var service = ObjectFactory.GetInstance<IPerformanceService>();
var showName = service.GetPerformanceTitle(showId);
return url.Action(MVC.Performance.Details(showId, showName.ToFriendlyUrl()));
}
}
Which is used like this:
<a href='<%= Url.ForShow(1)%>'>
Essentially I am trying to build a URL with a slug from an entity id. Maybe I'm just going about this in a really daft way.

I would not recommend doing this. Extension methods are generally best used for simple, well-known operations directly on a type. If your extension method is dependent on having an instance of another type, it is likely that it shouldn't be an extension method to begin with.
Consider making an actual service class that performs this functionality, and injecting it where it's needed. If you really need this in an extension method, consider wrapping the functionality your extension method requires in another static class/method, and avoid using any kind of injection or location.
Sharing some code might shed more light on your specific situation.

There is no way to inject dependencies into an extension method.
For ASP.NET MVC helpers, you are going to have to do some sort of service location - whether you bury that with some sort of abstraction is up to you.

You should NOT be calling structuremap directly in your extension method. Also, you should create a testable version that takes an IPerformanceService argument like below:
public static class ShowUrl
{
public static string ForShow(this UrlHelper url, int showId)
{
//Use the MVC DependencyResolver NOT Structuremap directly (DependencyResolver is using structuremap)
return url.ForShow(showId, DependencyResolver.Current.GetService<IPerformanceService>())
}
//For Unit Testing
public static string ForShow(this UrlHelper url, int showId, IPerformanceService performanceService)
{
var showName = performanceService.GetPerformanceTitle(showId);
return url.Action(MVC.Performance.Details(showId, showName.ToFriendlyUrl()));
}
}
Now you can pass in a concrete implementation of IPerformanceService in your unit test method.
Assert.Equal("TheUrl", url.ForShow(8, new PerformanceService());
More info on mocking UrlHelper: ASP.NET MVC: Unit testing controllers that use UrlHelper

Related

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

ASP.NET MVC Database localization

I'm developing an multilingual enterprise web site and I would like to store the localization in database.
I have read the following article which is very good but I personally think that is a an overhead and I can achieve the same much easy:
Extending the ASP.NET 2.0 Resource-Provider Model
I have already setup some ground but I'm not sure if my approach is fine. Basically I have created a service that is registers with DI.
public interface ILocalizedStringProvider
{
string GetLocalizedString(string key);
string GetLocalizedString(string key, string deafultValue);
}
Also i have created a Html helper like this
public static MvcHtmlString LocalizedString(this HtmlHelper helper, string key, string defaultValue)
{
if (string.IsNullOrEmpty(defaultValue)) return new MvcHtmlString("");
if (string.IsNullOrEmpty(key)) return new MvcHtmlString(defaultValue);
ILocalizedStringProvider localizedStringProvider = DependencyResolver.Current.GetService<ILocalizedStringProvider>();
if (localizedStringProvider == null)
{
return MvcHtmlString.Create(defaultValue);
}
string val = localizedStringProvider.GetLocalizedString(key, defaultValue);
if (string.IsNullOrEmpty(val))
{
return MvcHtmlString.Create(defaultValue);
}
return MvcHtmlString.Create(val);
}
Then the helper is simply invoked from the view.
First I want to know if this approach is good and if is not an anti-pattern.
Second my concern is this line:
ILocalizedStringProvider localizedStringProvider = DependencyResolver.Current.GetService<ILocalizedStringProvider>();
Is it maybe better to resolve the service ILocalizedStringProvider in the controller with constructor injection and let the controller populate the ViewBag with the localization's?
Thanks!
You can use my Griffin.MvcContrib project. It contains a ready to use MS SqlServer implementation for storing localization in the database.
Introduction: http://www.codeproject.com/Articles/352583/Localization-in-ASP-NET-MVC-with-Griffin-MvcContri
Administration
There is also an adminstration area which you can use to manage the localizations:
SQL Server setup
https://github.com/jgauffin/griffin.mvccontrib/wiki/SqlServer
Source code
The project is available at github: https://github.com/jgauffin/griffin.mvccontrib
Here is a very good one :
http://west-wind.com/westwind.globalization/
It offers :
DB storage
Resx Import/Export
Strong Type Class generation
it is rapidly added to your projects via Nuget, and you have the Full Source Code.. Awesome stuff

Dependancy issue with static utility classes with repository (.NET MVC project)

I have an MVC project with the standard IoC setup that uses StructureMap to inject repositories into controller constructors.
I also decided I wanted to have a static "utilities" class where I could have common methods that can be called by different controllers. So for example, I have:
public static IEnumerable<CountryCode> GetCountryList()
{
ICountryCodeRepository repo = ObjectFactory.GetInstance<ICountryCodeRepository>();
IEnumerable<CountryCode> countries = repo.GetAll();
return countries;
}
As you can see, that directly creates a repo object from the ObjectFactory. The problem, now, is that when I want to unit-test my controllers, I can mock the repos for the controllers, but not the repos in the utilities class (which the controller eventually calls) I'm sure there are other reasons why my utilities class is wrong, but this is what I see so far. I've also read some stuff saying what I have is bad design, I just don't know how to fix it.
I was thinking about having the GetCountryList() function to accept a repo object
GetCountryList(ICountryCodeRepository _repo)
and the calling controller would pass it in, but isn't that just creating another dependency concern because all controllers will have to know what the utility functions need?
Or is it possible to use StructureMap somehow to inject these utility methods?
It's at least OK that you know that what you are doing is bad design. That's fine and people reading this post will know it as well and avoid doing the same mistake as you.
But now to the point, you could use a provider in your static class:
public static class Foo
{
public static Func<ICountryCodeRepository> CountryRepoProvider =
() => ObjectFactory.GetInstance<ICountryCodeRepository>();
public static IEnumerable<CountryCode> GetCountryList()
{
return CountryRepoProvider().GetAll();
}
}
and now in your unit test you could mock it:
Foo.CountryRepoProvider = () => mocha;
or if you are using ASP.NET MVC 3 and you DI framework uses a dependency resolver you could improve this code by at least making it DI framework agnostic:
public static IEnumerable<CountryCode> GetCountryList()
{
var repo = DependencyResolver.Current.GetService<ICountryCodeRepository>();
return repo.GetAll();
}
Now in your unit test you could of course write a custom dependency resolver which will spit mocked instances of your services.
And now when you look at this code you might really say to yourself: What am I doing? I am writing a static class with one liner methods delegating to a repository I am fetching from the DI. What's the point when I can benefit from my DI framework to directly inject the instance of this repository wherever I need it and then simply call the method I need on it? What am I unit testing in those one liner static methods? Why am I wasting my time.
And if of course you had more complex logic to handle you would simply write a service layer which will take the necessary repositories as constructor dependencies and perform the complex business operations on them. Then you will simply configure your DI framework to inject those ready to be used instance of the service in your controllers or wherever you need it. See? No need of any static class. Weak coupling and unit testing friendly code.

ASP.NET MVC Configuration Class using IoC

In an MVC app, we the have need to create a configuration settings class that is needed throughout the app. It is a cross-cutting concern in that it is need in controllers, sometimes deep in the domain logic, as well as place like HtmlHelper extensions. The fact that it's needed is so many different places is what is tripping me up.
The class will wrap settings that are pulled from the web.config, as well as a table in a DB. The DB settings query will be cached so I'm not worried about that getting hit up for every request.
In years past I may have created some static type of class or singleton, but I don't want to lose the testability I have now. What would be the best way to instantiate this class and then to be able to access it through pretty much anywhere in the app?
I would continue to use a singleton. But a singleton which is wrapping an interface, which also makes it testable.
public class Configuration
{
private IConfiguration _config;
public static IConfiguration Instance { get { return _config; }}
public static void Assign(IConfiguration config)
{
_config = config;
}
}
Simply use Assign in global.asax or any of your unit tests.
If you want to do it the correct way, you should provide the configuration settings directly in the constructors of your objects.
Instead of
public class MyService
{
public MyService()
{
var confString = Configuration.Instance.GetConnectionString()
}
}
You would do:
public class MyService
{
public MyService(string confString)
{}
}
Finally, I would not have any configuration dependencies in HTML helpers. By doing so yuo are adding business logic to your views which breaks separation of concerns
I think the codeplex project mvccontrib provided some hooks to use
at least 3 IOC providers as far as I not windsor, structurmap, spring.net...
but I did not used it myself
you can find out more here
http://mvccontrib.codeplex.com/
and maybe you can look into the sourcecode of this project and see where you can go from there...
HTH
I would refactor my app not to use configuration everywhere. I use configuration in controllers only. My views do not have any logic, my domain model does just have business logic, not application logic.

How do I Access the RequestContext Outside the Controller?

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.

Resources