<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Categories</title>
        <link>http://wc4f.qsh.es/category/3.aspx</link>
        <description>Categories</description>
        <language>en-US</language>
        <copyright>Jeffrey Richardson</copyright>
        <generator>Subtext Version 2.1.0.5</generator>
        <item>
            <title>Category support in ASP.NET MVC nearly finished</title>
            <link>http://wc4f.qsh.es/archive/2009/02/25/8.aspx</link>
            <description>&lt;p&gt;I've finished implementing support in ASP.NET MVC for processing requests and rendering views using categories.  Only things left now is to add extension methods that simplify the process of using categories, as well as finish implementing discoverability (i.e. SiteMapProvider).&lt;/p&gt;
&lt;p&gt;In the future, I wish to also deal with inline page code.  I find it rather ugly, as well as having no page designer support. Although I do not use the page designer to design my page, I do tend to use it as a "quick preview," as well I tend to work with others who require page designer support.  I've gone through several possible ideas and implementations, but I believe I have settled on a single idea that should work well. I'll have updates later.&lt;/p&gt;
&lt;p&gt;I never specifically planned on releasing any software, but I believe some people out there might be interested in some of the software I talk about, so I've included what work I've done with category support thus far.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/8.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/25/8.aspx</guid>
            <pubDate>Wed, 25 Feb 2009 20:04:34 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/8.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/25/8.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/8.aspx</wfw:commentRss>
            <enclosure url="http://wc4f.qsh.es/Enclosures/MvcExtras.Categories.dll" length="15872" type="application/x-msdownload" />
        </item>
        <item>
            <title>Another approach to ASP.NET MVC categories</title>
            <link>http://wc4f.qsh.es/archive/2009/02/21/7.aspx</link>
            <description>&lt;p&gt;Last night I had an idea for a different approach for grouping related controllers into a category that made so much sense, I'm surprised I was able to imagine it.  The idea of actions being grouped into a controller parallels a set of methods being grouped into a class. Taking it a step further, grouping a set of controllers into a category would parallel grouping a set of classes into an assembly.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Under this approach, each category would be created as a separate project, referenced back into the main web application.  This has a few advantages over using attributes.  First, it allows real separation, as opposed to the superficial separation that attributes employ.  Second, it's much easier to cache the controllers into categories, as attribute lookups are no longer required, nor is it required to check that category has been added to the cache (as it can be added the moment the assembly is loaded).  It also enforces a design pattern that is much less fragile than attributes (which itself is much less fragile than current implementations I've found), and doesn't feel too restrictive.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;I plan on keeping both implementations in my framework, as I see they both have advantages over the other.  With many different features being added to my framework, I believe it will be necessary to split it into separate modules.  This will simplify adding needed features, without having to include everything.&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/7.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/21/7.aspx</guid>
            <pubDate>Sat, 21 Feb 2009 06:07:22 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/7.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/21/7.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/7.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Category support in ASP.NET MVC? Part 2</title>
            <link>http://wc4f.qsh.es/archive/2009/02/09/5.aspx</link>
            <description>&lt;p&gt;In order to support categories of controllers in ASP.NET MVC, one must create a new controller factory.  The IControllerFactory interface defines two methods to implement, CreateController, which passes in the controller name pulled from the route data, as well as the RouteContext itself, and ReleaseController, which occurs at the end of the request, allowing the controller to be freed.  One limitation of CreateController method is that it only gives the controller name, but not the category name.  This isn't much of an issue, it's possible to obtain the category name by calling the GetRequiredString method from RequestContext.RouteData object (this is the same method used to obtain the controller and action name as well).  The question now, how does one obtain a reference to the correct Controller type?  A quick assumption as to how it is done without categories would be to reflect until the correct controller is found, then returning that.  Based on this assumption, one would assuming finding a matching Controller, then checking the attributes to determine that the corresponding attribute is set.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;However, that's not how the default controller factory works, and for good reason.  It's very poor performance to reflect the entire set of types searching for the correct type.  Instead, the default controller factory creates what is known as a 'ControllerTypeCache' where it reflects through every type to find all matching controller types only once (when the application starts) and saves that list.  It uses a Dictionary&amp;lt;string, ILookup&amp;lt;string, Type&amp;gt;&amp;gt; to store this list.  A Dictionary is a one to one mapping between key and value, whereas a Lookup is a one to many mapping between key and value.  For each controller type that is found, it's name is derived, then that name is used to obtain the Lookup from the Dictionary (or create a new one if necessary).  Then, the namespace is taken from the controller type, and then used as a key to add the type to the Lookup.  So, each controller name is then mapped to one or more namespaces, which is then mapped to one or more types (more than one type with the same namespace and same name can occur if they are defined in separate assemblies).&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;A modified version of this same procedure can be used to support category lookup as well.  In this case, it might be preferable to store in an IDictionary&amp;lt;string, IDictionary&amp;lt;string, Type&amp;gt;&amp;gt;, where each category then maps to one or more controller names, which then map to one type.  The list can be easily generated using the following code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style="font-family: consolas; background: white; color: black; font-size: 10pt"&gt;     &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;&amp;gt;&amp;gt; GetAllControllerTypes() {&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: green"&gt;// Go through all assemblies referenced by the application and search for&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: green"&gt;// controllers.&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;&amp;gt;&amp;gt; controllerTypes = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: #2b91af"&gt;ICollection&lt;/span&gt; assemblies = &lt;span style="color: #2b91af"&gt;BuildManager&lt;/span&gt;.GetReferencedAssemblies();&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Assembly&lt;/span&gt; assembly &lt;span style="color: blue"&gt;in&lt;/span&gt; assemblies) {&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;[] typesInAsm;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;try&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            typesInAsm = assembly.GetTypes();&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ReflectionTypeLoadException&lt;/span&gt; ex) {&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            typesInAsm = ex.Types;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; controllerType &lt;span style="color: blue"&gt;in&lt;/span&gt; typesInAsm.Where(IsControllerType)){&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;string&lt;/span&gt; category = GetCategoryName(controllerType);&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(category)){&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (!controllerTypes.ContainsKey(category)) controllerTypes.Add(category, &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;&amp;gt;());&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;                controllerTypes[category].Add(GetControllerName(controllerType), controllerType);&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;     }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;return&lt;/span&gt; controllerTypes;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;Types can easily be looked up using the following code:  cache[categoryName][controllerName] (obviously, this is just a simple method demonstrating the structure; in order to prevent a NullReferenceException, you would want to use TryGetValue instead).&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/5.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/09/5.aspx</guid>
            <pubDate>Mon, 09 Feb 2009 20:04:25 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/5.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/09/5.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/5.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Category support in ASP.NET MVC?</title>
            <link>http://wc4f.qsh.es/archive/2009/02/06/4.aspx</link>
            <description>&lt;p&gt;For some time, I have been desiring a method for grouping a set of related Controllers into categories. A search for such a category style scheme showed me that, in the web MVC world, such a concept is known as areas, and I found a few examples of people implementing such features on top of ASP.NET MVC.&lt;/p&gt;  &lt;br /&gt;  &lt;p&gt;&lt;a href="http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx"&gt;http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.codeville.net/2008/11/05/app-areas-in-aspnet-mvc-take-2/"&gt;http://blog.codeville.net/2008/11/05/app-areas-in-aspnet-mvc-take-2/&lt;/a&gt;&lt;/p&gt;  &lt;br /&gt;  &lt;p&gt;Both of these are the same implementation, with the former having little flexibility and being very fragile, with the latter adding flexibility at the expense of complexity, while still being as fragile. To add to that, neither solution supports discoverability (something I will get to with a later post).&lt;/p&gt;  &lt;p&gt;My implementation will consist of adding the route name 'category' to the list of required route names, just like 'controller' and 'action'.  Also, the use of an attribute would declare the category of a controller.&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style="font-family: consolas; background: white; color: black; font-size: 12pt"&gt;     &lt;p style="margin: 0px"&gt;[&lt;span style="color: #2b91af"&gt;AttributeUsage&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;AttributeTargets&lt;/span&gt;.Class, AllowMultiple=&lt;span style="color: blue"&gt;false&lt;/span&gt;, Inherited=&lt;span style="color: blue"&gt;false&lt;/span&gt;)]&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;abstract&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CategoryAttribute&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;Attribute&lt;/span&gt; {}&lt;font face="Trebuchet MS"&gt; &lt;/font&gt;&lt;/p&gt;   &lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;This will allow one to inherit from CategoryAttribute and decorate their controller class with the corresponding CategoryAttribute.&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style="font-family: consolas; background: white; color: black; font-size: 12pt"&gt;     &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MainCategoryAttribute&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;CategoryAttribute&lt;/span&gt; { }&lt;/p&gt;      &lt;p style="margin: 0px"&gt; &lt;/p&gt;      &lt;p style="margin: 0px"&gt;[&lt;span style="color: #2b91af"&gt;MainCategory&lt;/span&gt;]&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MainController&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;Controller&lt;/span&gt; {&lt;/p&gt;      &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ActionResult&lt;/span&gt; Main() {&lt;/p&gt;      &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;return&lt;/span&gt; View();&lt;/p&gt;      &lt;p style="margin: 0px"&gt;    }&lt;/p&gt;      &lt;p style="margin: 0px"&gt;}&lt;/p&gt;   &lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;By defining the route using "{category}/{controller}/{action}/{id}" (note, in this example, {id} is not necessary), the following URL will activate the MainController.Main() method:&lt;/p&gt;  &lt;p&gt;Main/Main/Main/&lt;/p&gt;  &lt;p&gt;(I notice the lack of originality with naming the sections, and I apologize; I'm not the best at naming things, especially for example purposes.)&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;My next article will be more in depth about how this model actually works.&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/4.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/06/4.aspx</guid>
            <pubDate>Fri, 06 Feb 2009 19:40:49 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/4.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/06/4.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/4.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>