views:

367

answers:

2

I was just watching Scott Hanselman's presentation on ASP.NET MVC in San Francisco. After thinking about it for a while, I was stumped as to how to best approach building an ASP.NET MVC-based site that has a [portal|modular|multi-view] structure (pick your favorite definition).

To give you an idea of what I'm after, my company builds a lot of portal-style applications for out clients that incorporate a mapping module that can respond to it's own query strings and routes, tax parcel information module that similarly has its own view(s), document retrieval view that displays single and multiple documents...you get the idea. The critical part is that each module is truly standalone. If a user searches for a tax record by name they might see 10 results ("JOHN DOE" owns a few properties). Each result has a "Map it" link because the website application framework knows that there is a map module available. The "Map it" link sends the right request like http://myapp.com/taxparcel/map/123443. The map module controller responds to the external request by zooming to the map and highlighting the tax parcel.

The key to this whole flow is that both the tax and mapping modules are on the same web page.

So how does that fit in to the ASP.NET MVC box? Partials? Sub views? Multiple views for a single controller? If I'm just missing the obvious part of the documentation then feel free to lambast me publicly and include the link. Otherwise I'm wide open to suggestions.

+2  A: 

Well, your view model need to provide extension points. I assume that data for the view does contain those module parts, and is picked by the controller somehow:

public ActionResult Search(string text)
{
   var model = seachService.Search(text)
   // here either:
   // 1. model contains .Modules collection and is populated by the service, or
   // 2. controller does
   var viewmodel = new SearchViewModel(model, modulesService.GetModulesFor(model));
   // i.e. it adds modules-specific information to the view data
   return View(model);
}

Now, the modules-specific data is converted by SearchViewModel into something that View can use:

public interface IModuleSpecificViewPart
{
  public IList<string> GetAdditionalLinksForUser();
  public void RenderAdditionalInfo(Response response);
}

and your view does

<%= Model.Results[i] %>
<% foreach (var module in Model.ModuleSpecific) { %> 
<a href="<%=module.AdditionalLink%>">More</a> 
<% module.RenderAdditionalInfo(Response); %>
<% } %>

Or module view model can provide partial view name, etc. Notice that it's modules.GetModulesFor() and SearchViewModel that do the job - for example, SearchViewModel can do IoC.GetInstanceByType("ModuleViewModel" + passedModule.GetType().Name) - automatically picking up the specific module view model class.

This is the idea. It can be that I understand your question completely wrong - sorry if so.

One advice, I personally found that if I try to be too generic, it adds unneccessary complications to the project (I even wrote about it). I.e. yes your modules are unknown at compile time but you have to know something about them! They may add link to search result - here's the extension point for that. One can't images extension points for "anything", so first you'll need to list your specific cases.

queen3
A: 

I think queen3's reply is more suited to your specific problem but I thought I'd post my ideas on the general matter anyways.

I'm considering doing something similar using the techniques discussed in Matthew Abbott's blogpost. Using MEF, you can just drop a new dll into your portal to activate a module.

Having multiple modules on a single page is a bit tricker. RenderPartial could work but that's generally meant for adding code that works off the same view model. RenderAction on the other hand uses its own controller and model. I generally wouldn't favor using RenderAction in any other scenario because it breaks or at least convolves the MVC pattern. In this case however, it would only be used on a single page which is responsible for laying out multiple modules. All of your plugins could be regular MVC views,controllers and models.

Details on RenderAction can be found here.

Mr Grieves
Thanks for the additional perspective. Not checked out MEF yes but understand how it could help in general.
Dylan