<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>John Bennett&#039;s blog &#187; asp-net</title>
	<atom:link href="http://jtbennett.com/blog/tag/asp-net/feed" rel="self" type="application/rss+xml" />
	<link>http://jtbennett.com/blog</link>
	<description>Software and web development</description>
	<lastBuildDate>Tue, 08 Feb 2011 00:50:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<meta xmlns="http://www.w3.org/1999/xhtml" name="robots" content="noindex,follow" />
		<item>
		<title>The life and times of an ASP.NET MVC Framework request</title>
		<link>http://jtbennett.com/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request</link>
		<comments>http://jtbennett.com/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request#comments</comments>
		<pubDate>Mon, 16 Feb 2009 22:45:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp-net]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request/</guid>
		<description><![CDATA[[I recently wrote this up for some folks at work, and thought it was worth re-posting here.] In this post I&#8217;ll detail what happens during a request to the default ASP.NET MVC site that you get when you create a &#8230; <a href="http://jtbennett.com/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>[I recently wrote this up for some folks at work, and thought it was worth re-posting here.] </p>
<p>In this post I&#8217;ll detail what happens during a request to the default ASP.NET MVC site that you get when you create a new MVC project in Visual Studio.&nbsp; My goal is to list the major classes involved and how they interact.&nbsp; There is a lot more that goes on during a request, and I&#8217;ve completely skipped action filters.&nbsp; This is just the highlights. </p>
<p>First, there are some steps that happen at application start: </p>
<ul>
<li>The web.config file adds System.Web.Routing.UrlRoutingModule.&nbsp; During initialization, <strong>UrlRoutingModule</strong> attaches event handlers for HttpApplication&#8217;s PostResolveRequestCache and PostMapRequestHandler events.&nbsp; These handlers do some magic (using pre-existing extension points in ASP.NET) to ensure that requests in both IIS6 and IIS7, and for various versions of .NET, all wind up in the right place.
<li>The web.config file also adds <strong>MvcHttpHandler</strong>.&nbsp; Requests matching *.mvc are handled with it.&nbsp; This is also part of the goo that makes MVC work with different versions of IIS and .NET.
<li>Application_Start().&nbsp; This <strong>HttpApplication</strong> event handler is overridden in the Global class (Global.asax.cs).&nbsp; It calls the RegisterRoutes() method, also defined on the Global class.
<ul>
<li><strong>RegisterRoutes</strong>() informs the routing infrastructure which requests to route to which controllers and actions, how to populate action method parameters from the URL, and what the default parameter values are.&nbsp; It does this by adding Route objects to an ordered collection. </li>
</ul>
</li>
</ul>
<p>The application is now setup to begin accepting requests.&nbsp; Here are pseudocode and descriptions for what happens on each request.&nbsp; Note that wherever you see &#8220;httpContext&#8221;, the object is actually derived from the <strong>HttpContextBase</strong> class defined in System.Web.Abstractions.&nbsp; This avoids the web forms dependency on HttpContext, and allows for code execution and testing outside the context of a web request. </p>
<p>This could use a sequence diagram, and I hope to create one soon.&nbsp; In the meantime, you can try to follow along in Reflector (or the MVC source if you&#8217;ve downloaded it). </p>
<ul>
<li>The <strong>UrlRoutingModule</strong> event handlers do their magic, the result of which is the creation of an MvcHttpHandler object and a call to its ProcessRequest() method.&nbsp; MvcHttpHandler derives from UrlRoutingHandler, which is part of the routing API and implements IHttpHandler.
<li><strong>mvcHttpHandler.ProcessRequest</strong>():
<ul>
<li>routeData = <strong>RouteCollection.GetRouteData</strong>(httpContext);
<ul>
<li>In turn, calls <strong>route.GetRouteData</strong>() on each route in the collection. The collection is whatever we added during RegisterRoutes() at application startup, in order. The first route to return a non-null value wins the request.&nbsp; RouteData contains the names of the controller and action (both required), along with the values of any other tokens defined in the route URL format.
<ul>
<li>RouteData is important, as it carries request-specific data (e.g., URL token values) that are not present in HttpContext.&nbsp; The <strong>RequestContext</strong> object is an aggregation of HttpContext and RouteData, and is available to all later processing of the request. </li>
</ul>
</li>
</ul>
<li>mvcRouteHandler = routeData.RouteHandler; (MvcRouteHandler implements IRouteHandler, which is part of the routing API.&nbsp; MvcRouteHandler is just a very thin adapter between routing and Mvc.)
<li>mvcHandler = mvcRouteHandler.GetHttpHandler();
<li><strong>mvcHandler.ProcessRequest</strong>(httpContext);&nbsp; (MvcHandler implements IHttpHandler.)
<ul>
<li>Gets the controller name from the RouteData.
<li>Gets the singleton instance of <strong>DefaultControllerFactory</strong>.
<li>controller = <strong>factory.CreateController</strong>(requestContext, controllerName);
<li><strong>controller.Execute</strong>(requestContext);
<ul>
<li>Creates a ControllerContext, which is just the RequestContext plus a reference to the controller instance.
<li>Gets the action name from the RouteData.
<li>Creates an ActionInvoker
<li><strong>actionInvoker.InvokeAction</strong>(controllerContext, actionName)
<ul>
<li>Maps values in the RouteData to parameters on the action method with matching names
<li>If there are complex parameter types that can&#8217;t be directly mapped from RouteData values, the invoker instantiates an IModelBinder for each parameter and calls <strong>BindModel()</strong> on it to get the parameter value.
<li>Invokes the action method with all the parameters.
<ul>
<li>In typical usage, action methods get data, add that data to the ViewData dictionary and/or the Model property. Then the action method calls the controller&#8217;s View() method.
<li><strong>controller.View()</strong> method:
<ul>
<li>Gives each registered view engine an opportunity to &#8220;claim&#8221; the view. The default WebFormViewEngine uses the virtual path to locate the view. The default virtual paths it checks are:
<ul>
<li>~/views/{controller}/{action}.aspx and .ascx
<li>~/views/shared/{action}.aspx and .ascx </li>
</ul>
<li>View() returns a ViewResult object (derived from ActionResult) containing a reference to the view engine and the virtual path to the view. </li>
</ul>
<li>The action method typically returns the ViewResult it gets from View(). </li>
</ul>
<li>The invoker calls <strong>result.ExecuteResult</strong>():
<ul>
<li>When called on a ViewResult, this method asks the view to render itself:
<li><strong>view.Render</strong>(outputWriter)
<ul>
<li>Performs the rendering and writes the output directly to the outputWriter (which is the HTTP response stream). </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Removing dependencies between controllers and Linq DataContext classes with dependency injection</title>
		<link>http://jtbennett.com/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection</link>
		<comments>http://jtbennett.com/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection#comments</comments>
		<pubDate>Sat, 22 Dec 2007 15:30:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp-net]]></category>
		<category><![CDATA[dependency-injection]]></category>
		<category><![CDATA[linq]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[mvccontrib]]></category>
		<category><![CDATA[mvctoolkit]]></category>
		<category><![CDATA[windsor]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection/</guid>
		<description><![CDATA[In ScottGu&#8217;s most recent post on ASP.NET MVC, he demonstrates using a partial class for the NorthwindDataContext created by the Linq to Sql designer.&#160; In the partial class he creates some simple wrapper methods for the ProductsController to use when &#8230; <a href="http://jtbennett.com/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx">ScottGu&#8217;s most recent post on ASP.NET MVC</a>, he demonstrates using a partial class for the NorthwindDataContext created by the Linq to Sql designer.&nbsp; In the partial class he creates some simple wrapper methods for the ProductsController to use when retrieving and persisting data.&nbsp; However, the ProductsController is still tightly coupled to NorthwindDataContext.&nbsp; Let&#8217;s decouple them using an interface and some dependency injection&#8230;</p>
<p>If you want to follow along, you&#8217;ll need to <a href="http://www.scottgu.com/blogposts/mvc4/mvcapplication5.zip">download ScottGu&#8217;s sample</a>, which I&#8217;ll use as my starting point.&nbsp; The sample (MvcApplication5) uses the MvcToolkit, but I found I had to <a href="http://www.asp.net/downloads/3.5-extensions/MVCToolkit.zip">download MvcToolkit</a> and repair the reference to before I could successfully build and run the sample.</p>
<h3>Creating the IProductsRepository interface</h3>
<p>The first step is to create an IProductsRepository interface.&nbsp; We&#8217;ll use VS2008&#8242;s refactoring support to extract an interface from Scott&#8217;s NorthwindDataContext partial class.&nbsp; Open that file in the editor, right-click on the partial class declaration and choose Refactor &gt; Extract Interface.</p>
<p><a href="http://jtbennett.com/blog/wp-content/uploads/2010/07/1RefactorContextMenu_22.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="1-RefactorContextMenu_2[2]" border="0" alt="1-RefactorContextMenu_2[2]" src="http://jtbennett.com/blog/wp-content/uploads/2010/07/1RefactorContextMenu_22_thumb.png" width="244" height="174"></a> </p>
<p>Name the interface IProductsRepository and select just the five methods that Scott added in the partial class.</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/2-ExtractInterfaceDialog_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Select methods to include in interface" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/2-ExtractInterfaceDialog_thumb.png" width="189" height="244"></a></p>
<p>That will create IProductsRepository.cs in the Models folder with the new interface.</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/3-IProductsRepository_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="The new IProductsRepository interface" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/3-IProductsRepository_thumb.png" width="244" height="98"></a></p>
<p>It also adds the interface to the NorthwindDataContext declaration.&nbsp; Now we can go to the ProductsController in the Controllers directory and change the northwind field to be of type IProductsRepository.</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/4-ChangeFieldToInterface_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Change private field to interface type" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/4-ChangeFieldToInterface_thumb.png" width="244" height="141"></a></p>
<p>At this point, we have a problem.&nbsp; Both the Create() and Update() action methods call SubmitChanges() on the data context.&nbsp; When we try to build, the compiler tells us that the SubmitChanges method isn&#8217;t part of the IProductsRepository interface.&nbsp; The whole goal here is to reduce the coupling between the controller and the Linq-generated DataContext.&nbsp; So we&#8217;re going to move the Linq code into the partial class and access it through the interface we just created.</p>
<p>Let&#8217;s start with Create().&nbsp; Create() calls AddProduct() on the data context, which looks like this:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/6-AddProductMethodBefore_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="AddProduct() before" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/6-AddProductMethodBefore_thumb.png" width="244" height="31"></a></p>
<p>Let&#8217;s add a call to SubmitChanges() to AddProduct():</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/7-AddProductMethodAfter_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="AddProduct() after" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/7-AddProductMethodAfter_thumb.png" width="244" height="42"></a></p>
<p>We have to remove SubmitChanges() from Create():</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/8-CreateMethodAfter_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Create() after" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/8-CreateMethodAfter_thumb.png" width="244" height="70"></a></p>
<p>There is no method in our IProductsRepository interface that the controller can call when updating a product, so we&#8217;ll create a SaveProduct() method in the interface and implement it in NorthwindDataContext.&nbsp; The only thing our implementation of SaveProduct() will do is call SubmitChanges().&nbsp; So Update() looks like this:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/9-UpdateMethodAfter_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Update() after" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/9-UpdateMethodAfter_thumb.png" width="244" height="68"></a></p>
<p>And SaveProduct() like this:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/10-SaveProductMethod_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="SaveProduct() method" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/10-SaveProductMethod_thumb.png" width="244" height="33"></a></p>
<h3>Setting up for dependency injection with Windsor</h3>
<p>At this point, everything works as before, we&#8217;ve just added an interface and moved some calls to SubmitChanges().&nbsp; ProductsController and NorthwindDataContext are still tightly coupled.&nbsp; For the next part, we&#8217;re going to use <a href="http://en.wikipedia.org/wiki/Dependency_injection">dependency injection</a> and our new interface to break the coupling.&nbsp; For some background on dependency injection and why you might want to use it, see this article and links by <a href="http://www.jamesshore.com/Blog/Dependency-Injection-Demystified.html">James Shore</a>.</p>
<p>There are a number of tools that will do dependency injection for you.&nbsp; We&#8217;re going to use Windsor from the <a href="http://www.castleproject.org/">Castle Project</a>.&nbsp; We&#8217;ll also use MvcContrib, a community-driven project on CodePlex that is developing useful add-ons to ASP.NET MVC.&nbsp; One of those add-ons is a WindsorController, which allows us to easily use dependency injection on our controllers.</p>
<p>You&#8217;ll also need to download the latest release of the <a href="http://www.codeplex.com/MVCContrib/">MvcContrib project</a>.&nbsp; I&#8217;m using the beta version 0.0.1.32 in this sample.&nbsp; We need to add a couple of references to the MvcToolkit assemblies.&nbsp; When you download the binaries version, you&#8217;ll have a bin directory with the assemblies and a Samples directory with some code that we&#8217;ll use below.</p>
<p>Add references in MvcApplication5 to:</p>
<ul>
<li>Castle.Core.dll
<li>Castle.MicroKernel.dll
<li>Castle.Windsor.dll
<li>MvcContrib.dll
<li>MvcContrib.Castle.dll. </li>
</ul>
<p>Now we need to modify our Global.asax.cs file so that our web application automatically creates a Windsor Container.&nbsp; All of these changes are below are also shown in the sample app provided in the MvcContrib download.</p>
<ul>
<li>Add using statements for the Castle.Core and Castle.Windsor namespaces.
<li>Implement the IContainerAccessor interface, which has a single property named Container.
<li>Add a static field to hold the container, and a static property to wrap it. </li>
</ul>
<p>Here&#8217;s what they look like so far:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/12-ImplementIContainerAccessor_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Changes to Global.asax.cx" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/12-ImplementIContainerAccessor_thumb.png" width="244" height="199"></a></p>
<p>Next up is to instantiate the container and make it aware of all the controller classes in our application.&nbsp; This is done by looking for all types in the current assembly that can be cast to the IController interface.</p>
<ul>
<li>Add a using statement for the MvcContrib.ControllerFactories namespace.
<li>Copy in the InitializeWindsor() method from the sample app.
<li>Refactor the route handling setup from Application_Start() to a separate method named AddRoutes().
<li>Change the Application_Start() handler to call InitializeWindsor() and AddRoutes(). </li>
</ul>
<p>The end result in Global.asax.cs is:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/13-AddInitializeWindsorMethod_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="InitializeWindsor() method" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/13-AddInitializeWindsorMethod_thumb.png" width="244" height="136"></a></p>
<p>Two changes to the sample code are required.&nbsp; The first change is to tell the WindsorContainer to use the web.config file to get the configuration values.&nbsp; We&#8217;ll go into the config settings in the next section.&nbsp; Here all we need to do is pass into the WindsorContainer constructor a new XmlInterpreter().&nbsp; This tells the container to use the current app.config or web.config file.</p>
<p>The sample uses a controller class named WindsorController to get access to the assembly containing all the controllers.&nbsp; Since we don&#8217;t have a WindsorController type, our second change is to:</p>
<ul>
<li>Add a using statement for the MvcApplication5.Controllers namespace.
<li>In the InitializeWindsor() method (line 42 in the screenshot) change &#8220;typeof(WindsorController)&#8221; to &#8220;typeof(HomeController)&#8221;.&nbsp; I use HomeController, since most ASP.NET MVC applications will have one of those. </li>
</ul>
<p>After these changes, the two lines in InitializeWindsor() look like this:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/13-InitializeWindsorChanges_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="InitializeWindsor() changes" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/13-InitializeWindsorChanges_thumb.png" width="244" height="19"></a></p>
<h3>Injecting the repository into ProductsController</h3>
<p>Getting back to our ProductsController class, remember that we changed the northwind field to be of type IProductsRepository, but we still populated it with an instance of NorthwindDataContext. What we want is for ProductsController to know nothing about NorthwindDataContext.&nbsp; Any class that implements IProductsRepository should work just fine for retrieving and saving products.</p>
<p>First, we&#8217;ll remove the assignment of the NorthwindDataContext instance.&nbsp; While doing this, we&#8217;ll change the field name from &#8220;northwind&#8221; to &#8220;repository&#8221; to make it more generic.&nbsp; VS2008&#8242;s refactoring support makes this a breeze.&nbsp; Then we&#8217;ll add a constructor that takes a parameter of type IProductsRepository.&nbsp; (Make sure the IProductsRepository interface is declared as public, since we didn&#8217;t do that earlier.)&nbsp; The result is:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/14-AddProductsControllerConstructor_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Add constructor for DI" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/14-AddProductsControllerConstructor_thumb.png" width="244" height="68"></a></p>
<p>We&#8217;re now ready to tell Windsor: &#8220;Whenever you create a ProductsController, pass a NorthwindDataContext into its constructor.&#8221;&nbsp; We do that through a config section in web.config.&nbsp; First declare a section for castle in the &lt;configSections&gt; element and add a &lt;castle&gt; element as follows:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/15-CastleWindsorConfig_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Configure Windsor" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/15-CastleWindsorConfig_thumb.png" width="244" height="73"></a></p>
<p>What we&#8217;re telling Windsor here is that whenever a controller has a constructor parameter of type IProductsRepository, give it a new instance of NorthwindDataContext. </p>
<p>At this point, we can run the application to see that it all works just like it did in Scott&#8217;s original version.&nbsp; The difference now is that our controller and data context are no longer tightly coupled.&nbsp; If we wanted to change from Linq to some other ORM tool, or to move the Products table to a different Linq data context class than the rest of Northwind, before we&#8217;d have to make a bunch of code changes.&nbsp; Now all we have to do is update our web.config file to point Windsor at a class that implements IProductsRepository and we&#8217;re done.</p>
<p>Enjoy.&nbsp; And please comment on what&#8217;s confusing, what I glossed over too quickly, and what I spent too much time explaining.&nbsp; I&#8217;m still getting the hang of this and welcome any suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ASP.NET MVC preview released</title>
		<link>http://jtbennett.com/blog/2007/12/asp-net-mvc-preview-released</link>
		<comments>http://jtbennett.com/blog/2007/12/asp-net-mvc-preview-released#comments</comments>
		<pubDate>Tue, 11 Dec 2007 02:12:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp-net]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2007/12/asp-net-mvc-preview-released/</guid>
		<description><![CDATA[I&#8217;m far from the first to post about it, but I&#8217;m excited enough for a &#8220;me too!&#8221;.&#160; Full details available from ScottGu, as usual.&#160; And MVC isn&#8217;t the only thing included.&#160; AJAX, Silverlight, and Data Services (aka Astoria) are also &#8230; <a href="http://jtbennett.com/blog/2007/12/asp-net-mvc-preview-released">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m far from the first to post about it, but I&#8217;m excited enough for a &#8220;me too!&#8221;.&nbsp; <a href="http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-3-5-extensions-ctp-preview-released.aspx" _tesavedurl="http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-3-5-extensions-ctp-preview-released.aspx">Full details available from ScottGu</a>, as usual.&nbsp; And MVC isn&#8217;t the only thing included.&nbsp; AJAX, Silverlight, and Data Services (aka Astoria) are also in there.&nbsp; Great stuff to dig into&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2007/12/asp-net-mvc-preview-released/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>From ASP to WebForms to ASP.NET MVC</title>
		<link>http://jtbennett.com/blog/2007/12/from-asp-to-webforms-to-asp-net-mvc</link>
		<comments>http://jtbennett.com/blog/2007/12/from-asp-to-webforms-to-asp-net-mvc#comments</comments>
		<pubDate>Sun, 09 Dec 2007 13:56:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp]]></category>
		<category><![CDATA[asp-net]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[webforms]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2007/12/from-asp-to-webforms-to-asp-net-mvc/</guid>
		<description><![CDATA[A long, long time ago I was one of many web developers working with classic ASP.&#160; While anyone who worked (or still works, heaven help you) with ASP will tell you how quickly a site could become unmaintainable, there was &#8230; <a href="http://jtbennett.com/blog/2007/12/from-asp-to-webforms-to-asp-net-mvc">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A long, long time ago I was one of many web developers working with classic ASP.&nbsp; While anyone who worked (or still works, heaven help you) with ASP will tell you how quickly a site could become unmaintainable, there was one thing I rather liked abou it:&nbsp; it did not abstract away much of the underlying web technology.&nbsp; HTTP was always there, and the only HTML that was rendered was what you wrote yourself.&nbsp; Nothing happened that you didn&#8217;t do yourself.</p>
<p>When ASP.NET and WebForms came along, I was always doing &#8220;View source&#8221; to see exactly what those magical server controls were doing.&nbsp; Once I understood how it worked, I began to trust it.&nbsp; Over time, I spent less and less time worrying about the exact HTML that was rendered.&nbsp; The productivity benefits of WebForms and server controls were the main focus.&nbsp; I learned to trust the automagic-ness.&nbsp; You can create some amazing things very quickly.</p>
<p>There are certainly drawbacks to WebForms:&nbsp; only one server form (with runat=&#8221;server&#8221;) per page, out-of-control viewstate if you weren&#8217;t careful, postbacks always going to the same page, etc.&nbsp; But over time, the community developed techniques to mitigate those drawbacks and make them workable.&nbsp; I still believe the WebForms model is a very good thing.</p>
<p>As web development has become a major part of the development effort in most organzations, the roles have become more specialized.&nbsp; Unlike the old days, a single person is not typically creating images in Photoshop, writing HTML (and now CSS), writing JavaScript, writing WebForms and writing business and data access classes.&nbsp; In my company, we have designers who create page mock ups in Photoshop; interface developers who turn those into HTML, CSS and JavaScript; and server-side developers who write server-side code.&nbsp; (Let&#8217;s leave aside the issue of whether that&#8217;s the &#8220;right&#8221; way to organize a team.&nbsp; The fact is that many companies, including mine, do it that way.)</p>
<p>There is an impedence mismatch between these roles and the way WebForms work.&nbsp; Say your interface engineer turns the Photoshop page comps into a bunch of HTML files.&nbsp; Your server-side developers &#8212; looking at those HTML files in the context of the entire site &#8212; break them up into master pages, pages, and controls in some logical way that optimizes the development of the server-side code.&nbsp; Then the inevitable changes come.&nbsp; Do you have the interface developers rewrite the HTML, and the server-side developers try to figure out how to apply the changes in the server-side structure?&nbsp; Or do you have the interface developers start working in your .ascx and .aspx files directly?&nbsp; If they don&#8217;t have Visual Studio or a full dev environment set up, how can they effectively do the edit-refresh cycle to do their work?&nbsp; The same types of issues crop up when you talk about a global.js JavaScript file vs. RegisterClientScript(), and with CSS files vs. ASP.NET themes.</p>
<p>Those challenges help explain why I&#8217;m so excited about the new <a href="http://weblogs.asp.net/scottgu/archive/tags/MVC/default.aspx" _tesavedurl="http://weblogs.asp.net/scottgu/archive/tags/MVC/default.aspx">ASP.NET MVC</a> framework.&nbsp; Everything I&#8217;ve seen so far looks like a combination of the power and productivity of WebForms, the total control of the rendered HTML of classic ASP, and a very nice alignment with the division of labor found in many web development shops.</p>
<p>I&#8217;m writing this post in <a href="http://graffiticms.com" _tesavedurl="http://graffiticms.com">Graffiti</a> beta 1, which also uses an MVC model and NVelocity as the view engine.&nbsp; The views are really clean and simple, and it&#8217;s simple to write powerful server-side helpers to produce modern CSS-styled HTML.&nbsp; I can&#8217;t wait to have that structure baked into ASP.NET.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2007/12/from-asp-to-webforms-to-asp-net-mvc/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Annoyance with web project build process</title>
		<link>http://jtbennett.com/blog/2006/11/annoyance-with-web-project-build-process</link>
		<comments>http://jtbennett.com/blog/2006/11/annoyance-with-web-project-build-process#comments</comments>
		<pubDate>Sun, 12 Nov 2006 22:03:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp-net]]></category>
		<category><![CDATA[master-pages]]></category>
		<category><![CDATA[msbuild]]></category>
		<category><![CDATA[web-application-projects]]></category>
		<category><![CDATA[web-deployment-projects]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2006/11/annoyance-with-web-project-build-process/</guid>
		<description><![CDATA[This week I ran into a minor annoyance with our process for building web projects. We use VS2005 web application projects, along with web deployment projects, and in the deployment project we choose not to make the web site updatable &#8230; <a href="http://jtbennett.com/blog/2006/11/annoyance-with-web-project-build-process">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This week I ran into a minor annoyance with our process for building web projects. We use VS2005 <a href="http://webproject.scottgu.com/" _tesavedurl="http://webproject.scottgu.com/">web application projects</a>, along with <a href="http://weblogs.asp.net/scottgu/archive/2005/11/06/429723.aspx" _tesavedurl="http://weblogs.asp.net/scottgu/archive/2005/11/06/429723.aspx">web deployment projects</a>, and in the deployment project we choose not to make the web site updatable &#8212; all the aspx and ascx files are compiled. We then use MSBuild to copy everything into an output directory like so:</p>
<ul>
<li>1.0.61112.123
<ul>
<li>Production
<li>QA
<li>Staging </li>
</ul>
</li>
</ul>
<p>With the non-updatable option selected in the web deployment project, all the .ascx and .master files are removed during compilation. They&#8217;re compiled, so we don&#8217;t need them anymore, right? Right. Well, when we copy files to the output directory, our /MasterPages and /UserControls directories don&#8217;t have any files, so those directories don&#8217;t get recreated in the output. Unfortunately, it looks like we need those empty directories. When we run the site, ASP.NET seems unable to find either the master pages or any user controls if the directories they were originally in don&#8217;t exist.</p>
<p>Our workaround is to create an empty &#8220;dummy.config&#8221; file in each directory that we need to have show up in the running site. Config files are harmless, and ASP.NET won&#8217;t let them be retrieved through a browser. Alternatively, we could add a step to our build file that deletes all the dummy.config&#8217;s after copying to the output.</p>
<p>My question is: Why does ASP.NET need the empty directories in order to locate the compiled .master and .ascx classes? Or are we just doing something wrong in the deployment project or in our overall build process?</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2006/11/annoyance-with-web-project-build-process/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

