The Magic Behind MVP / MVC Frameworks
One of the things I learned at DevConnections 08 is the magic behind ASP.NET MVC, and how it actually works. Beside the UrlRouting (which you can do with HttpModule stuff), it's pretty easy and relies a lot on Activator.CreateInstance(). As seen in my post about creating a csv from list, you can read about it here.
The magic is...shhh...
|
![]() |
Yeah, no-DUH you say. Well it took MS this long to come up with it for public consumption when MVC has been around for decades. Anyhooo.
NOTE: I'm more of an MVP guy, so this is geared toward using the MVP's Presenter rather than the MVC's Controller. They're similar patterns, 'cept MVP is a bit more decoupled (and deprecated...), so in my example below, you can replace 'Presenter' with 'Controller' if it makes you fuzzy, because really, that's where all the work gets done.
Here we go.
A request comes in for blah.com/hotguitars.aspx. Your UrlRouting can match the url up with the correct view [handler] and rewrite its path to that page handler. In this case, I'd most likely use the DefaultView since the page lives off of the root (/).
On PageLoad the presenter factory is going to take the url and try to figure out which class to instantiate [return] to make the contents for the view. Each of the classes returned implement Presenter, which implements IPresenter... so I can code to the interface, which is nicer. (Notice the interfaces. I'm an interface kinda dude, because they're hot when it comes to testing).
Ok, so here's the little POC for you.
// Presenter class implements this because all *Presenter // classes need to have a DoIt() method public interface IPresenter { void DoIt(); } public class Presenter : IPresenter { public Presenter() { } public virtual void DoIt() { } } public class PresenterFactory { //return the url minus hyphens private static string GetPresenterName(Regex re, string url) { return re.Match(url).Groups[1].Value.Replace("-",""); } //get the url private static Regex rePage = new Regex(@"/(.+?)\.aspx", RegexOptions.IgnoreCase);
This is the sexiness....
public static Presenter GetPresenter(Page page) { // this is blah.com/hotguitars.aspx string rewrittenUrl = page.Request.RawUrl; string presenterName = GetPresenterName(rePage, rewrittenUrl); //here is where you make sure you have a HotGuitarsPresenter string className = "BunchaJunk.Presenters." + presenterName + "Presenter"; // get the type, throw error, and ignore case Type type = Type.GetType(className, true, true); // create an instance of the correct Presenter/Controller and return it return (Presenter)Activator.CreateInstance(type, new object[] { page }); } } public interface IBasicPage { string HtmlTitle { get; set; } string HtmlMetaKeywords { get; set; } string HtmlMetaDescription { get; set; } string MainContent { get; set; } } public class HotGuitarsPresenter : Presenter { private IBasicPage ibp; public HotGuitarsPresenter(IBasicPage ibp) { this.ibp = ibp; } public override void DoIt() { ibp.HtmlMetaDescription = "Hot stuff!"; ibp.HtmlMetaKeywords = "jackson, paul reed smith"; ibp.HtmlTitle = "Here are the hottest guitars at csharptocsharp!"; ibp.MainContent = "paul reed smith, jackson, gibson"; } }
Here is how it is called from aspx code behind
public partial class _Default : Page, IBasicPage { protected void Page_Load(object sender, EventArgs e) { //coding to the interface is the cat's meoooooooooooow IPresenter p = PresenterFactory.GetPresenter(this); p.DoIt(); } public string HtmlTitle { get; set; } public string HtmlMetaKeywords{get;set;} public string HtmlMetaDescription { get; set; } public string MainContent{get;set;} }
Here is how it's used in the aspx
<title><%=HtmlTitle%></title>

















