views:

248

answers:

2

So... I have a business object/manager which is going to generate emails.

These emails will contain links to various content on the website... and therefore needs to understand about MVC routing.. or at least how to generate URLs for the website...

However my business object will not have access to a RequestContext etc and the email generation is not necessarily the result of a web request to a website (I have a dispatcher which runs on a background thread which will be generating the emails)

Any ideas how I can generate my urls without having access to a request - and therefore being unable to use URLHelper...

Thoughts?

+1  A: 

I prefer to define schema and make both routing and business logic aware of it. Means different implementations of the same URL schema.

Some reasons why:

  1. Your routing mechanism could change. For example in feature you can switch to url_rewrite module.
  2. Possible issues with load-balanced installation.
  3. You do not need even to try to use URLHelper in undocumented way.

BTW, you can replace HttpRequest from URLHelper easily. We used to use this for unit-testing. For more information just search for unit testing of the HttpContextBase or look at examples in source code of the MvcContrib. This can help to instantiate URL helper and all related stuff in non hosted environment. But I still do not think that this is a good idea.

Mike Chaliy
Well.. so long as I wrap my implementation within an interface this shouldnt be an issue? For example IRouteHelper?Anyway... not sure what you meant by "I prefer to define schema and make both routing and business logic aware of it" - how can you use schema driven development to define your routing?
ListenToRick
Are you suggesting I mock the HttpRequest?
ListenToRick
I do not see any issues in IRouteHelper if this works for you. As you may noted suggestion to have different implementations is one that I will choose if I face same question (what I prefer). By schemas I mean that URL schema (e.g. in spec defined that products should be at Invetory/Product/11654)Mocking is sort of test doubles that checks if it was executed. Of course I do not suggest this. What I suggest is to implement dependencies of the UrlHelper. Actually you do not need UrlHelper it just wrapper on RouteCollection.
Mike Chaliy
I'm thinking that I will define a "RouteManager" which consumes an xml definition of my routes. In the web project I will add an extension method which knows how to populate a RouteCollection from the internal representation of the route schema. In my Business layer I will add an extension which knows how to generate URLs from the schema. Thoughts?
ListenToRick
This is something that I refered as "different implementations" and yes I think this will work.
Mike Chaliy
+1  A: 

In order to get at the UrlHelper outside of the controller, you need to feed it and the routing data the HttpContext. Here's an example:

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;    

HttpContextBase context = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper =  = new UrlHelper(new RequestContext(context, RouteTable.Routes.GetRouteData(context)));
ZaChickster