Aftab Qauder

  Home  |   Contact  |   Syndication    |   Login
  3 Posts | 0 Stories | 1 Comments | 0 Trackbacks

News

Archives

Sunday, June 12, 2011 #

Part 3 – Creating the view engine

[Download the code as a .Zip here]





Looking at the precompiled view from earlier we can see it derives from WebViewPage, however the view engine wants a view that implements IView. To get around this we create a wrapper class for the view. As you can see we pass the view into the constructor.

The code below has been taken from

Here

but I've stripped it down for simplicity. You may wish to refer back to Chris van de Steeg's code for a more robust example.

The most important part of the example below is the Render method which is what MVC will call when it attempts to use the view.





Now we will look at our custom view engine. To handle out views we create a ViewManager, this simply contains a list of views.We can use this ViewManager resolve the correct view by name.



When MVC wants a view it will call CreateView on the View Engine. As you can see all we are doing is calling the ViewManager to find the view by name and returning a wrapper object to MVC.  MVC will then call the Render method on the view.




If we look at the method FindView we can see what’s being passed in as a parameter. The naming convention here is being defined by the ViewLocationFormats in our ViewEngine.


In this example we’re keeping it quite simple and just using the view name to return a view from the views list. In a real situation it would be quite probable that more than one controller would have  a methodwith the same name on it so you would probably have to take the controller into account as well.

 

Finally navigating to the correct controller and view will render the view to the browser.


Part 2 – Creating the controller factory

[Download the code as a .Zip here]

 


As we are are storing the controllers in a separate assembly we need to give the system some way of locating them. When a path is requested MVC will query the controller factories and request the relevant controller.

To allow us to map to our custom views we will create a custom controller that will look in the Windsor container for a view and if it exists return it.

In the global.asax file we create the container and then tell it to install Windsor installers in a specific directory. In the example below we are pointing it to the directory we created earlier as the output directory for the class library



 

In the assembly we create a Windsor Installer which implements IWindsorInstaller. This registers all the controllers and views. register all the views. If we look at the section which registers the views we can see it says:

“Register all types  that exist in this assembly that implement IController, for each of the found controllers give it a name tag based on the classtype and specify the lifestyle of it as transxient”

 

In this example we are giving each controller a name due to the fact that we resolve controllers by name , but we'll come to that later.

At this point if we ran the project we would see all the controllers found in this assembly were in the container

 






Our Controller factory is pretty simple apart from one fact. Typically when you create a ControllerFactory you will locate the controller in GetControllerInstance. However in this example MVC doesn’t know about the types so the parameter controllerType is null.

So to locate the controller we use the controller name. This is why we registered each controller with a name earlier.




Finally we tell MVC to use this controller factory in the Global.asax file





At this point we’ve done enough to route requests to the correct controller, however MVC still won’t know how to load the views.

 

In section 3 we will look at creating a custom view engine to locate our views.

[Part 3 - View Engine]

 


 

 

In this article we will use ASP.NET MVC 3 and the Windsor Container to explore ideas around modular software design. The principal aim of this guide is to show you how to store controllers and views in a separate assembly and load them at run-time.

[Download the code as a .Zip here]

 

Part 1 - Setting up the project and environment


In this guide the solution will have two projects. One will be the main MVC3 application MVC.Modular and the second will be a standard class library that contains all the MVC assets (Views and Controllers) WebStuff.  We will place the logic that wires up the controllers and views in the global.asax file in MVC.Modular.






We will use Castle Windsor to load the assets from an assembly. However to make this example simpler we will load that assembly from a well know directory.In this case we will create  directory called “Modules” within the web application we will use this as the target for the class library.



If we look at the project settings of the WebStuff so we can see it outputs the directory above



 

Both applications will need to access the Windsor container so add references to  windsor to both projects.




Next drag the web.config file from web project to the class library. The views will use this file for the namespace lookups. Alternatively you could add the namespaces directly to the views.
You will also need to add the following references to the Class library

System.Web
System.Web.Routing
System.Web.MVC

You will also need to add a reference to System.Web.WebPages, on my machine this was located at:


c:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies\System.Web.WebPages.dll

We will be using complied Razor views with our view engine. As mentioned earlier these will be located in the Assembly rather than the web project. To allow the complied views to be used you will need to install an application which compiles them for you. I used the one in

Download David Ebbo’s Raxor complier

There also seems to be one by Chris van De Steeg but I used David Ebbo’s one.

Rick click your view, go to properties and set the custom tool as ‘MvcRazorClassGenerator’. This will mean this tool is run every time you save the file

 



 

You will now notice that your view will now have a code behind file.



If we look at Greeting.cshtml we can see our view is extremely simple. It contains a HTML formatting and a div containing the words “HelloWorld”.



Looking at the code behind file you can see what is executed in the view. The contents of the file is written as a literal near the bottom.


 

In part two we will look at the construction of a ControllerFactory to help MVC locate controllers in the assembly.

 

[Part 2 - Controller Factory]