Dependency Injection
I gave a talk in my local .NET developer community about Dependency Injection and would like to share it with everyone on my blog as well.
What Is Dependency Injection?
- Dependency Injection (DI) is a design pattern.
- Its goal is to help us build loosely coupled components.
- It works by allowing selection among multiple implementations of a given dependency interface at runtime, or via configuration files, instead of compile time.
- DI contains three parts: dependency consumer, dependencies defined as interface contracts and dependency injector –> A consumer specifies the service contract by interface, and the injector selects an implementation.
A Simple Example
If we write an email component called SmtpEmailSender to send messages, keep decoupling in mind, we would implement an interface that defines all of the public functions required to send email, say the interface is called IEmailSender.
Now we are writing another component that needs to send emails, say a UserGroup which is able to send out news letters. We will only let it send out emails by referring only to the interface methods, so there is no direct dependency between UserGroup and SmtpEmailSender.
With this design, there is no direct dependency between UserGroup and SmtpEmailSender, so we could replace SmtpEmailSender with another email sender, or even use a mockup for testing purposes.
However, to put this thing into code without dependency injection, C# doesn’t provide a built-in way to easily create objects implementing interfaces, except to create an instance of the concrete component. We may end up with:
public class UserGroup { private IEmailSender sender; private List<User> users; public UserGroup() { sender = new SmtpEmailSender(); } public void SendNewsLetter(NewsLetter letter) { foreach(User u in users) { sender.SendEmail(u.EmailAddress, letter); } } }
Sorry, we are only part of the way to loosely coupled components, as we are creating the concrete object SmtpEmailSender in our UserGroup class. It’s sort of even worse as UserGroup depends on both IEmailSender and SmtpEmailSender now.
What we need is a way to obtain objects implementing given interface without needing to create the object directly. The solution of this problem is called Dependency Injection (DI), also known as Inversion of Control (IoC).
In this case, to avoid the direct reference of SmtpEmailSender, what we want to do is to pass implementations of the required interfaces to the class constructor:
public class UserGroup { private IEmailSender sender; private List<User> users; public UserGroup(IEmailSender sender) { this.sender = sender; } public void SendNewsLetter(NewsLetter letter) { foreach(User u in users) { sender.SendEmail(u.EmailAddress, letter); } } }
Thus we have broken the dependency between UserGroup and SmtpEmailSender. The UserGroup constructor demands an object that implements the IEmailSender interface, but it doesn’t known, or care, what the object is and is no longer responsible for creating it.
Dependency Injector
The dependencies are injected into UserGroup at runtime; that is, an instance of some class that implements the IEmailSender interface will be created and passed to the UserGroup constructor at runtime. There is no compile-time dependency between UserGroup and any class that implements the interfaces it depends on.
But, how do we instantiate the concrete implementation of interfaces without creating dependencies somewhere else in our application? Where are we going to create our SmtpEmailSender and send it to our UserGroup constructor?
The answer is a Dependency Injector, a.k.a. DI container or IoC container. This is a component that acts as a broker between the dependencies that a class demands and the concrete implementation of those dependencies.
We register the set of interfaces or abstract types that our application uses with the Dependency Injector, and tell it which concrete classes should be instantiated to satisfy dependencies. As in this example, we would register IEmailSender interface with the container (injector) and specify that an instance of SmtpEmailSender should be created whenever an implementation of IEmailSender is required. Whenever we need an IEmailSender, we go to the Dependency Injector and are given an implementation of the class we registered as the default concrete implementation of that interface – in this case, SmtpEmailSender.
We don’t need to create the Dependency Injector. There are some great open source and freely licensed implementations available.
A real world example with our UserGroup and SmtpEmailSender classes in an ASP.NET application using Autofac as the Dependency Injector:
First we need to setup Autofac and register IEmailSender and SmtpEmailSender in Global.asax
public class Global : HttpApplication, IContainerProviderAccessor { static IContainerProvider _containerProvider; public IContainerProvider ContainerProvider { get { return _containerProvider; } } protected void Application_Start(object sender, EventArgs e) { var builder = new ContainerBuilder(); //Register dependencies builder.RegisterType<SmtpEmailSender>().As<IEmailSender>(); _containerProvider = new ContainerProvider(builder.Build()); } }
Note: we need to setup Autofac HttpModules in Web.config as well. The reason is we have no direct access to an ASP.NET Web Form application's default page factory therefore cannot perform constructor injection. If you are familiar with HttpModules, you know they will be executed along the ASP.NET Web Form page life cycle so it can perform logic, for example, set up setter injection before any function you add to a page being called, even Page_Init().
In the world of ASP.NET MVC, it's totally different, what you only need to do is to replace the default controller factory if you only need to achieve dependency injection for controllers, or you can even replace the default application-wide dependency resolver (which is only available for you in MVC 3+) to easily perform application-wide dependency injection.
Now we need a starting point to hook up our dependency injection, a class either its instantiation (for constructor injection) or retrieving of its properties (for setter a.k.a. property injection) can be intercepted by our DI container (injector). As in this example we are coding an ASP.NET web form application, we have no access to the web page factory, we will use setter injection with Autofac’s HttpModule. So in our UserGroupEmail page’s code-behind:
public partial class UserGroupEmail : Page { //This property will be set by Dependency Injector at run-time public IEmailSender sender { get; set; } protected void btnSendEmail_Click(Object sender, EventArgs e) { UserGroup = new UserGroup(sender); UserGroup.SendNewsLetter(new NewsLetter(Hello World!)); } }
Note: here we are performing property(setter) injection.
Actually, a Dependency Injector's job is more than this, it will need to take care of instance life cycle, etc. Additionally, the cool part is it can even resolve dependency chain. For example, if our SmtpEmailSender is referring to an interface IEmailFacility which we map to DefaultEmailFacility in our Dependency Injector's configuration. And we have SmtpEmailSender's constructor designed like the following:
public class SmtpEmailSender : IEmailSender { private IEmailFacility facility; public SmtpEmailSender(IEmailFacility facility) { this.facility = facility; } //... ... ... }
The Dependency Injector is smart enough to instanciate SmtpEmailSender with the mapped concrete class DefaultEmailFacility during run-time when a SmtpEmailSender is asked for IEmailSender, and this chain dependencies resolution can go on and on.
Dependency Injector Comparison
There are many different dependency injectors which are available on .NET Platform. I grabbed the following speed test for all the major ones from http://philipm.at/2011/0808/. You can access this link for more details, however, I will list the result graph here for easy access.
The "Sgl" refers to singleton instance and "Trans" is short for transient. For singleton every time when an interface is called, the injector will hand over the same instance of the concrete class. On the other hand, transient setup will give a new instance for every request.
DI Advantages
- Build decoupled and readily pluggable components.
- Make our lives easier while doing testing especially unit testing.
- More and more....
Remark
not every relationship needs to be decoupled using an interface. The decision is really about how complex the application is, what kind of testing is required, and what the long-term maintenance is likely to be. We may choose not to decouple or use dependency injection for simple applications targeting a small domain model, as it is an overkill.
In a nut shell, if your software design is good, Dependency Injection will make it better. If it's bad, Dependency Injection won't be able to help. Moreover, there is no need to intentionally separate functions in different classes to enforce Dependency Injection when it's not necessary. The scope should always be matching your model. Dependency Injection is a design pattern, but not a requirement.
HTML5 is here, Adobe gave up Flash on Mobile, so what’s next?
After years' of painful effort, facing the forceful repulse from almost all major mobile devices, Adobe finally gave up on Flash and will no longer putting eggs in this basket.
Apparently, big name companies propping HTML5 won this battle, and HTML5 is undeniably going to become the prevailing leader of next generation web applications. Apple has always been here, Google the same and Microsoft just dumped Silverlight and put on the same shoe. As the big 3 got the agreement unlike the past, we have to ask, is this just a battle for the conqueror HTML5 to replace Flash? Or something else more furtive?
Actually the defeat of Adobe Flash is not about itself, although over the past years there were numerous complaints against its performance and stability.
AJAX, Sometime It Is Just an Overkill
AJAX is one of the trends in web developer community. Actually, today, for every major website, the usage of AJAX is intense. If you disable JavaScript in your web browser, you will find most of the websites you hit become dysfunctional in some sense, more or less: either you cannot post a web form as before, or part of its content could not be rendered properly. Yes, now we use AJAX to fetch data and render and to validate a form and post asynchronously.
However, this article is not about the beauty and usefulness of AJAX, which is well understood and appreciated in the community by developers and web users, enough to say. I want to talk about the addiction to AJAX which can be found in countless many of web developers: they just simply want put AJAX wherever it can be put, no matter fit or not.
Remember the purpose of AJAX which is to improve user experience for example the flow of data transfer in a post and update situation is hidden from end user without refreshing the whole page. Watch out, the point here is to improve user experience but not asynchronous post nor partial render. If your usage of AJAX does not improve user experience, it's still called AJAX, but useless AJAX, or even worse, it can frustrate end users.
The problem of many web developers is, they are more fond of new technologies but do not have a thorough understanding of user experience. They often time throw AJAX in a web project because they think it is cool and tech-wise awesome. However, the general purpose of a web surfer did not change these years, when he/she browser a website, his/her goal is still to locate information he/she is looking for directly and readily, no matter it's a information portal or a social network.
Long story short, if your AJAX gadget post data without disturbing they browsing the rest of the page, it's totally cool, but if your usage of AJAX causes trouble deterring them from getting information they need, they are frustrated. A good example is Twitter's fancy usage of automatic loading tweets you received when you scrolling down the page. They obviously forget that the usage of AJAX is still computer resource consuming and let you end up with a slowly responding or even crashed site. Moreover, it disabled you from locating tweets at a specific time, sorry, you are not allowed to jump to a certain tweet or have a direct view of how many tweets you get, you have to scroll it. Actually it's true on many other websites as well, especially for information-based websites, where a plain fast web interface which allows you navigate to wherever you want is more sound than fancy popping up and scrolling. When someone is headed for a piece of information, he/she wants to locate it as quick as possible. In this situation, how fast they can find information is the dominant factor determining user experience, not fancy gadgets or visual effects.
In a nut shell, whenever and wherever you want to use AJAX, first ask yourself, is it going to truly improve user experience? If not, you better stick to a simple design, because simple is fast, and simple is elegant. Do not make AJAX an overkill.
How to Stream Sopcast Channel to Your Xbox 360 via Windows Media Center, High Quality, No VLC, No TVersity!
I sometimes watch soccer games on Sopcast as most of them are not broadcasted in North America. As my computer monitor is relatively small compared to my LCD TV and I do not want to connect TV to my desktop, I often wonder if I could stream Sopcast video to TV via my Xbox 360.
I googled a lot, but the only viable method I found on Internet is to set up both VLC and TVersity as middle ware. Then let VLC re-stream Sopcast video to TVersity and use TVsersity to monk a video library in local network for Xbox 360 access.
However, this approach goes ridiculously terrible, most of the time I didn't even be able to connect to TVersity video feed in my Xbox 360 and even I succeeded the picture quality is worse than what I got in Sopcast directly and disconnected quite often.
Is there another way around? As my Xbox is a Windows Media Center extender to my desktop and I use Windows Media Center on it to play downloaded video and audio files on my desktop(which is the Windows Media Center host machine), why not go with Windows Media Center? It's a universal truth that the quality of video stream will be better if we reduce the middle tiers.
As Windows Media Center on Xbox 360 works exactly the same way as on local computer, this problem goes to if we could watch Sopcast content in Windows Media Center on desktop.
The good point about Sopcast is that it automatically stream video in a Windows Media Center(and Player) supported format once it is playing something to your computer through HTTP protocal at port 8902 by default. For example, suppose you are playing a video channel on Sopcast, then you can watch it with your Windows Media Player as well by opening it, clicking File > Open URL and typing in http://127.0.0.1:8902.
Unfortunately, Windows Media Center does not support adding live video stream feed by inputting URL address. (Actually there may be some workaround hack to break the rule by playing around its online TV feature, but I didn't dig into that direction). But, it can open video files in your desktop's video library!
Bingo! You can figure it out now, can't you? Anyways, let me write the instruction down.
There is a type of media file supported by Windows Media Center which contains only meta-data specifying the real location of video data or the address of an online video stream feed and its extension is .ASX, so:
- In any folder on your desktop which is included in your video library thus accessible in Windows Media Center, create a blank text file and rename it to whatever.asx
- Edit it with any kind of text editor, for example, simply Note Pad
- Type in the following as its pure content
<ASX version="3">
<Entry>
<ref href="http://127.0.0.1:8902"/>
</Entry>
</ASX>
Here we go, simple and easy! You can then open it in Windows Media Center and watch the video Sopcast is currently playing!
To watch it on Xbox 360 now is straightforward, on your Xbox 360, navigate to My Xbox > Windows Media Center > Pictures + Videos > Video Library and open your whatever.asx in the folder you created it in. And yes, the video quality on TV now is exactly the same as you watch on Sopcast, if you get a HD channel, then it's HD on your TV and there is no disconnection or distortion!
Note: To play your whatever.asx in Windows Media Center(both on desktop and Xbox), you need first run Sopcast and let it play something, or nothing will be streamed to port 8902.
Note: One of the fun part is when you change the channel playing in Sopcast, the new Channel will also be broadcasted at port 8902 so you do not need to deal with Windows Media Center to switch channel.
Note: Of course you need to first connect your Xbox and desktop to the same local network, have Windows Media Center on your desktop and setup Xbox as a Windows Media Center Extender, how to setup WMC Extender can be found here on Microsoft website. http://www.microsoft.com/windowsxp/mediacenter/extender/owner/mcxsettup.mspx
Hope this guide will help you, enjoy watching Sopcast on TV via your Xbox 360
Website Auto Deployment Using Web Deploy with Team Foundation Server 2010 MSBuild in Visual Studio 2010
Build service is one of the greatest features in Team Foundation Server once setup in team develop environment as it can not only be triggered manually but also by check-ins or even scheduled. It brings convenience to and improves the performance of the develop team by managing solution builds flexibly and providing instant visual updates.
However, by default, it will only build the solution in place or at most copy output files to a drop folder. For teams working on web applications, if they want to test the built application on a testing server, they will have to manually deploy the compiled solution or use the website publish feature in Visual Studio.
Fortunately, as we could modify the underlying MSBuild arguments being called during the build process by updating the advanced settings in the build definition defined for our projects, we could let the build process execute the website publish operation automatically within the process.
The publication will be exactly the same as we publish a website manually by clicking Build -> Publish ***
Note that to enable publishing through Web Deploy, you need to setup IIS to support it, a helpful article can be found on IIS' official site at http://learn.iis.net/page.aspx/421/installing-web-deploy/
Thus similarly, we could define the publish method, service URL, Site/application and others in the build definition as well, but this time instead of selecting in a GUI panel, we will have to type in MSBuild arguments.
You could find your project's build definition or create a new one with the help of Team Explorer. Once opening its setting panel, select the Process tab on the left and then expand the 3.Advanced node on the right side inside the Build process parameters.
Then click the MSBuild Arguments and type in something like:
/p:DeployOnBuild=True
/p:DeployTarget=MsDeployPublish
/p:MSDeployServiceURL=*.*.*.*
/p:DeployIISAppPath="YOURSITE"
/p:CreatePackageOnPublish=False
/p:MsDeployPublishMethod=WMSVC
/p:AllowUntrustedCertificate=True
/p:UserName=YOURUSERNAME
/p:Password=YOURPASSWORD
Note that there should be a space between each parameter when you type them in.
DeployOnBuild When set to True, it enables auto deployment within build process.
DeployTarget When set to MsDeployPublish, we tell MSBuild to deploy with Web Deploy which you have setup on your testing server.
MSDeployServiceURL This is the URL of your testing server or somewhere you want to deploy your web application.
DeployIISAppPath This is the path of the site in IIS you want to deploy to, e.g. if you have a site called "DevelopSite" in IIS -> Sites, you can set it to "DevelopSite" then, remember the quotes.
CreatePackageOnPublish When set to True, a package of your web application will be generated for archival purposes, you do not need such package for deployment here.
MsDeployPublishMethod This is how you are going to publish your site to IIS through Web Deploy. WMSVC means you are going to publish through Windows Management Service. On the other hand, you could set it to RemoteAgent in case you are going to publish through Remote Agent Service.
AllowUntrustedCertificate This is straightforward, note that in many cases you will need to set it True for you testing server may not have a truested certificate.
UserName and Password are the credentials for an account on the testing server which have the privilege to use Web Deploy towards the certain site you set in DeployIISAppPath.
Note that the MSDeployServiceURL may be slightly different between WMSVC and RemoteAgent, for WMSVC, it's <HostedRemoteServer> or https://<HostedRemoteServer>:8172/Msdeploy.axd; for RemoteAgent, it's http://<RemoteComputerName>
Now we have the auto deployment set up, whenever then your team queue a build, the latest web application compiled will be deployed to your testing server automatically within the process.
How to: Increase Concurrent Requests Limit to Benefit from Asynchronous Requests in ASP.NET 3.5
Although ASP.NET 4.0 is now the trend on .NET Framework for web application development. Many firms and developers are still working with ASP.NET 3.5. Among them, many are not aware that by default in ASP.NET 3.5, the MaxConcurrentRequestsPerCPU is set to only 12 per CPU, no matter whether those requests are asynchronous or not. 12 may be sufficient for regular requests because they are usually finished quickly, but way not enough for asynchronous requests which in general take significant amount of waiting time.
Asynchronous requests are used in situations where you do not want to block a user from viewing a page while part of the content on the page relies on slow resources like a static file on hard disk, a complex result from database or an external web service. However, while MaxConcurrentRequestsPerCPU is set to as little as 12, no surprisingly in most of the case user experience won't benefit any from it. For example, in a regular ASP.NET site which has an application thread pool of 100 worker threads, if 12 users have issued asynchronous requests, no other asynchronous requests can be invoked until some of the previous ones being completed, given that dozens of worker threads are still sitting idle in the pool which could be assigned to new asynchronous requests.
Actually, based on the observation, the performance of an ASP.NET site which enables asynchronous requests won't benefit much for less than 50 concurrent requests. Thus we could clearly see the bottleneck for a value 12 MaxConcurrentRequestsPerCPU in an ASP.NET 3.5 site. Fortunately, in ASP.NET 4.0, MaxConcurrentRequestsPerCPU is increased to 5000 by default. But in case you have to work with ASP.NET 3.5 and want to benefit with your asynchronous requests, you need to tweak your server setting following either of the two approaches listed below:
- Use regedit to modify your server's registry. Create a DWORD value called MaxConcurrentRequestsPerCPU at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0, containing a large value such as 5000, or even 0 to mean "unlimited".
-
Include the following in your sever's \windows\Microsoft.NET\Framework\v2.0.50727\aspnet.config:
<system.web> <applicationPool maxConcurrentRequestsPerCPU="5000" maxConcurrentThreadsPerCPU="0" requestQueueLimit="5000" /> </system.web>
Note: If you are running IIS on a non-server OS, the default application pool may only contain 10 worker threads. In such case, you won't benefit from increasing MaxConcurrentRequestsPerCPU. But it is rarely a problem in real world because most of our product servers will run server OS.
Using Overridden HTTP Method in ASP.NET MVC
In recent years, many websites implement their light-weight web services and APIs REST-fully instead of using SOAP. Representation State Transfer(REST) style, compared to SOAP, gives meanings to URLs and uses the full range of HTTP methods, such as GET, POST and DELETE, to specify operations on the business entities described by those URLs.
For example, a REST-ful web service may use a URL http://www.example.com/Product/102 to represent a certain product, and perform obtaining product information, updating product information or deleting product information actions based on whether the incoming HTTP request is a GET, a POST or a DELETE.
If you have built such a REST-ful web service, it all works as long as the service consumers interact with web services are capable of using the full range of HTTP methods. Anyone making calls directly from server-side code written in .NET or other programming language like Java and Ruby has no problem with it. And in traditional ASP.NET Web Forms, it won't be a headache as well as instead of directly issuing the HTTP request, developers actually write code reacting to server control events and may send out request in the server-side control event handler which utilizes the full .NET Framework.
However, some mainstream client technologies, including HTML forms and even Adobe Flash are not not capable of using arbitrary HTTP methods, and are limited to sending only GET and POST requests. This introduces difficulties to ASP.NET MVC because MVC view pages contain only plain UI markups in general and oftentimes use directly HTML forms to issue request. This is great use of the idea of separation of concern and is the advantage of MVC, but is restricted by HTML weakness by not letting you specify HTTP methods in a form directly.
ASP.NET MVC has a built-in workaround for these client limitations. If a client wishes to send, say, a DELETE request, it can do so by actually sending a POST request and adding an extra parameter called X-HTTP-Method-Override with the value set to DELETE. If ASP.NET MVC finds such a key/value pair in the query string, form post collection or the HTTP headers, it will treat that value as overriding the actual HTTP method.
Note: ASP.NET MVC will only take X-HTTP-Method into account if it's combined with a POST request. If you set it in the query string with a GET request, it will simply be ignored. Essentially, GET requests should only perform read operation. Thus it will not conflict with HTTP standards.
To submit a plain HTML form with an overridden HTTP method in a MVC view page towards a ASP.NET MVC powered REST-ful web service, you can use the Html.HttpMethodOverride() helper method to add the appropriate key/value pair to an HTML form, as shown below:
<% using(Html.BeginForm("Product", "Product", new { ProductID = 102 })) { %> <%= Html.HttpMethodOverride(HttpVerbs.Delete) %> <input type="submit" value="Delete Product" /> <% } %>
The markup will be rendered by the view engine as something like the following depending on your routing settings:
<form action="/Product/Product/102" method="post"> <input name="X-HTTP-Method-Override" type="hidden" value="DELETE" /> <input type="submit" value="Delete Product" /> </form>
As you can see, it's attached to the form in a hidden field and can be retrieved when the form is submitted on the server within the form post collection.
If you are not working with ASP.NET MVC to consume your web service but with Adobe Flash, similarly, you could issue a HTTP Post request with X-HTTP-Method_Override key value pair added to either the header or simply attach it to the query string.
On server-side, the built-in method selectors such as [HttpPost], [HttpPut] respect HTTP method overriding because when they need to know the incoming request's HTTP method, they don't look at Request.HttpMethod but instead call Request.GetHttpMethodOverride(). This GetHttpMethodOverride() method will return the HTTP method if it is anything other than HTTP POST. But on the other hand, for a HTTP POST request, it will look for its X-HTTP-Method-Override key/value pair in the priority order of Headers > Form > Query String. If present, the value from the pair will be returned instead.
Therefore, if you want to respect HTTP method overriding in your own code, always remember to check Request.GetHttpMethodOverride() to determine a request's HTTP method instead of the traditional Request.HttpMethod.
Roundup: ASP.NET MVC Request Processing Pipeline
ASP.NET MVC's request processing pipeline shares many things in common with traditional ASP.NET Web Forms for they both take advantage of IIS sits underlying. However, unlike ASP.NET Web Forms, MVC gives you much more flexibility, you can modify any piece to your own liking, and even rearrange or replace components outright. The most significant difference is the place where routing (of course you can do routing alike MVC in traditional ASP.NET Web Forms, but it's not by default) and controllers kick in, and filters extend your capability to a larger scale as well.
This article will guide you through this infinitely extensible request processing pipeline and mostly discuss the four major steps involved to help you grab the big idea and comprehend what is going on behind the scene.
1.IIS
Internet Information Services, as Microsoft's web server system, works as the backbone of ASP.NET request processing. When each HTTP request arrives the server, a kernel-mode Windows device driver called HTTP.SYS will first classify the request based on its requested URL, port and IP address combination and then forward it to a registered application such as an IIS web site.
Essentially, ASP.NET MVC is built upon ASP.NET core, ASP.NET must be enabled for its application pool to guarantee ASP.NET MVC to work properly. When you create such a site in IIS, an application pool properly setup shall be assigned which is a pool of ASP.NET worker threads to take care of HTTP requests. You could tinker with many settings for application pools such as its managed pipeline modes, but that aspect is distracting from this article's purpose and will not be discussed here.
When an incoming request reaches an ASP.NET enabled IIS web site, ASP.NET kicks in and a worker thread from the application pool is dispatched to cope with that request. It notifies each registered HTTP module that a new request is starting. HTTP modules are .NET classes which implement IHttpModule interface that you can plug into the ASP.NET request processing pipeline. They are commonly used to handle certain events such as routing and information logging in a request's life cycle.
One particularly important HTTP module is registered by default in any ASP.NET MVC application: UrlRoutingModule. This module is the beginning of the core routing system which plays the most important role in the second step of request processing pipeline. If you are working on MVC 2 targeting .NET 3.5, you will find this module registered in your web.config file. On the other hand with .NET 4, UrlRoutingModule is removed from web.config and is referenced in machine-wide configuration by default. To see it's setup and running, you can take a look at Modules under IIS tab for your site in Internet Information Services(IIS) Manager.
2. Core Routing
System.Web.Routing assembly is invoked when UrlRoutingModule gets involved in processing a request. The core job of routing is about to recognize and parse incoming URL, setting up a request context data structure that subsequent components can use whatever they wish such as ASP.NET MVC uses it to transfer control to the relevant MVC controller class and to supply action method parameters.
Core routing for ASP.NET MVC will first check if the incoming request's URL is towards a static file (e.g. an image file or a style sheet file) on the disk. If so, core routing will simply pass by and leave it to IIS. IIS will serve them back to clients directly so that the process can be done efficiently.
On the other hand, if the incoming URL doesn't target a static file on disk, for example, it's mapped to a MVC controller, the core routing system will investigate its active configuration to figure out how to handle that incoming URL.
How routing is directed is configured in a static collection called System.Web.Routing.RouteTable.Routes. Each entry in this collection represents a distinct URL pattern your application wish to accept, for instance, /Shop/Catalog/{ID}, and constraints which limit the range of acceptable values for each parameters. Additionally, each entry will supply a route handler - an object which implements IRouteHandler thus it can take over and process the request. The RouteTable.Routes collection in an ASP.NET MVC application is usually setup by adding code to a method called RegisterRoutes() in Global.asax file.
To match a certain incoming request, the core routing system looks through RouteTable.Routes collection from top to bottom, picking the first entry that matches the URL pattern. Having found the matching entry, routing transfers control to that entry's specified route handler, with a request context data structure that describes the route entry and parameters parsed from the URL. MVC framework then gets in on the action.
3. Controllers and Actions
Reaching this step, core routing system has selected a particular entry in RouteTable.Routes, and has parsed any routing parameters out of the URL and packed them inside a request context data structure. Now is the time for controllers and actions to enter the scene.
In general, for ASP.NET MVC applications, almost all route entries specify one particular route handler: MvcRouteHandler. It is the built-in default route handler for ASP.NET MVC and it knows how to take the request context data and invoke the corresponding controller class. It does so by using a controller factory object. By default, the DefaultControllerFactory is used, however it can be replaced by custom controller factory in case special concern is raised for example dependency injection needs.
When a corresponding controller is picked by the controller factory object, its Execute method is called. Execute is the only method defined in the IController interface and every controller class must implement such interface:
public interface IController { void Execute(RequestContext requestContext); }
Note that the requestContext parameter provides all the request context data constructed by the routing system, including parameters parsed out from the incoming URL request. It also provides access to the Request and Response objects.
In most of the cases, you will work with high-level controller classes which wrap and hide the low-level details of the Execute method defined in IController interface. Thus you basically won't write data to response stream directly. Instead, you return an action result that describes the intended output in your controllers. For instance, you return a ViewResult if the goal for such controller is to render a view, or a RedirectToRouteResult if you want redirect request to a different action method or a different controller. MVC framework will then take care of executing that result at the appropriate moment in the request processing pipeline.
Note that filters can be attached onto a controller class or an action method and inject extra logic that runs before or after action methods, or before or after action results are executed. Filters are extremely flexible and their logic can be run at many possible moment during this step of the request processing pipeline.
In a nut shell, controllers and actions are the central pillars of the whole ASP.NET MVC framework.
4. Action Results and Views
At this point, the MVC framework will ask the ActionResult object returned by your controller to execute. The ActionResult does whatever that type of ActionResult does, either return a string to browser, issue an HTTP redirection or the most fun part to render a view.
The ActionResult which does the job of rendering a view is namely ViewResult. This one is able to locate and render a particular view, passing along whatever ViewData structure the action method has constructed. It does so by calling a "view engine" (for example, web form view engine for MVC 2 and razor view engine for MVC 3) determined by the controller.
In traditional ASP.NET Web Forms, each web form ASPX page have a dedicated pipeline on its own, starting with on-the-fly ASPX/ASCX compilation and running through a series of events known as the page life cycle. ASP.NET MVC tells a different story here. Its view pages are simple and contain only UI logic. There is no code-behind files nor web form page life cycle is involved, which save you from the marsh from a smart UI design to a much better architecture imposes separation of concerns.
------------------------------------------------------
The following work flow diagram will help you better comprehend ASP.NET MVC request processing pipeline.

ASP.NET MVC: Difference between web.config under Views and in Root Folder
Unlike ASP.NET Web Forms, when you create a MVC project in Visual Studio, by default it has two web.config files, one under Views folder while the other in the root. Not surprisingly, these two in general server for different purposes.
/Views/web.config
This is not application's main web.config file. It usually contains directive instructions like custom web.config files you generate inside sub-folders in a traditional ASP.NET Web Form application. By default, it contains setting to inform the web server not to serve any .aspx files under /Views for they should be rendered by a controller yet not directly accessible as in a web forms application. Additionally, this file contains configuration needed to make the standard page compiler work properly with ASP.NET MVC view syntax.
Example: auto generated /Views/web.config in ASP.NET MVC 2 project. MVC 3 is similar.
<?xml version="1.0"?> <configuration> <system.web> <httpHandlers> <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/> </httpHandlers> <!-- Enabling request validation in view pages would cause validation to occur after the input has already been processed by the controller. By default MVC performs request validation before a controller processes the input. To change this behavior apply the ValidateInputAttribute to a controller or action. --> <pages validateRequest="false" pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <controls> <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" /> </controls> </pages> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <handlers> <remove name="BlockViewHandler"/> <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /> </handlers> </system.webServer> </configuration>
/web.config
Root folder web.config is essentially similar to its counterpart in a traditional web forms application. However, a MVC root web.config contains more setting by default which setup MVC related assemblies and helpers and make them available in your view pages. If you are using MVC 2 targeting .NET 3.5, you will see routing module in your root web.config, but in .NET 4, routing is a core part set up in machine-wide configuration and such setting is removed from root web.config.
Example: auto generated /web.config in ASP.NET MVC 2 project. MVC 3 is similar with slight difference because of the newer assemblies.
<?xml version="1.0"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=152368 --> <configuration> <system.web> <compilation debug="true" targetFramework="4.0"> <assemblies> <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </assemblies> </compilation> <authentication mode="Forms"> <forms loginUrl="~/Account/LogOn" timeout="2880" /> </authentication> <pages> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> </namespaces> </pages> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false"/> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
Note: Here is a catch when you are developing ASP.NET MVC applications. If you want to set up site-wide behavior such as binding custom modules, you should always put them into root folder web.config. /Views/web.config is in general for the purpose of directive instructions. If you misplace setting in it, it may cause bugs which are hard to figure out. Thus always look up both web.config files if you are facing weird setting problems.




