<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Christopher Bennage : MVC</title><link>http://devlicio.us/blogs/christopher_bennage/archive/tags/MVC/default.aspx</link><description>Tags: MVC</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Things I’d Like To Present</title><link>http://devlicio.us/blogs/christopher_bennage/archive/2010/01/08/things-i-d-like-to-present.aspx</link><pubDate>Fri, 08 Jan 2010 11:32:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:54940</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;In case you are not familiar with &lt;a href="http://visitmix.com/" target="_blank"&gt;MIX&lt;/a&gt;, it is a conference from Microsoft focusing on the collaboration of design and development. Admittedly, the sessions tend to favor the developer, but there is always excellent design and UX content.&lt;/p&gt;  &lt;p&gt;&lt;a title="voting for MIX sessions" href="http://visitmix.com/opencallvote/?query=Christopher%20Bennage" target="_blank"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;margin-left:0px;border-top:0px;margin-right:0px;border-right:0px;" title="Mix10_Vote_grn_240" border="0" alt="Mix10_Vote_grn_240" align="right" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/christopher_5F00_bennage/Mix10_5F00_Vote_5F00_grn_5F00_240_5F00_44742D31.jpg" width="184" height="244" /&gt;&lt;/a&gt; There was an open call for presentations this year and the community gets to choose which of the proposals will be selected. There are a number of &lt;a href="http://visitmix.com/opencallvote/" target="_blank"&gt;excellent proposals&lt;/a&gt; and I encourage you to go check out the list and vote for the sessions that you are genuinely interested in. (Even if you won’t be attending, the sessions will be broadcast.)&lt;/p&gt;  &lt;p&gt;Here are some sessions that I proposed for MIX10:&lt;/p&gt;  &lt;h3&gt;Cross Compiling Games for Silverlight &amp;amp; XNA&lt;/h3&gt;  &lt;p&gt;Our friend and Silverlight MVP, &lt;a href="http://blogs.silverarcade.com/silverlight-games-101/" target="_blank"&gt;Bill Reiss&lt;/a&gt;, has created an incredible library that enables you to cross compile XNA games for Silverlight. The library is called &lt;a title="a library for cross compiling XNA and Silverlight games" href="http://silversprite.codeplex.com/" target="_blank"&gt;SilverSprite&lt;/a&gt; and we feature it on Silver Arcade. (Wow, that’s a lot of ‘silvers’ in one paragraph.)&lt;/p&gt;  &lt;p&gt;In this session, we’d write a simple game for XNA (discussing some of the basic of game dev along the way) and then port the game over to Silverlight.&lt;/p&gt;  &lt;p&gt;This is an area where I wish I could spend more time. I love game development, but it’s always taking a back burner to other projects.   &lt;br /&gt;&lt;a title="Cross Compiling Games for Silverlight &amp;amp; XNA" href="http://visitmix.com/opencallvote/Entry?entryId=CROSSC046" target="_blank"&gt;[vote for this]&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;LinqToSQL and EntityFramework Profilers: Case Study&lt;/h3&gt;  &lt;p&gt;If you aren’t already familiar with the UberProf suite of ORM profilers, you can read tales of the development on &lt;a href="http://ayende.com/Blog/category/561.aspx" target="_blank"&gt;Ayende’s blog&lt;/a&gt;. Rob and I built the UI side of the application, and we learned a lot in the process. I’d like to do a talk were we discuss the challenges of the project, how we solved them, and what we did wrong. &lt;/p&gt;  &lt;p&gt;Yes, NHProf will be included too. (I submitted a case study for it last year, and it didn’t get picked. I have to sneak it in).&amp;#160; &lt;/p&gt;  &lt;p&gt;A few interesting aspects: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;we built this using MVVM, but well before &lt;a href="http://www.codeplex.com/caliburn" target="_blank"&gt;Caliburn&lt;/a&gt; reached maturity. &lt;/li&gt;    &lt;li&gt;the four separate apps (NHProf, EFProf, L2SProf, HProf) all use a single code base.&lt;/li&gt;    &lt;li&gt;we’re about to port the project from WPF to Silverlight.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a title="LinqToSQL and EntityFramework Profilers: Case Study" href="http://visitmix.com/opencallvote/Entry?entryId=LINQTO047" target="_blank"&gt;[vote for this]&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Silver Arcade: Case Study&lt;/h3&gt;  &lt;p&gt;This is a presentation that Rob and I have made a couple of times. Most recently at the Orlando .NET Users Group. We walk through the actual code for &lt;a href="http://www.silverarcade.com" target="_blank"&gt;Silver Arcade&lt;/a&gt; explaining the philosophy, design choices and mistakes we made along the way.&lt;/p&gt;  &lt;p&gt;For MIX, we would focus more design and UX choices, such as the separation of the behaviors from the views. However, we like to have a lot of audience interaction and tend to follow where ever the questions led (especially those leading questions that &lt;a href="http://scottdensmore.typepad.com/" target="_blank"&gt;Scott Densmore&lt;/a&gt; tends to ask). &lt;/p&gt;  &lt;p&gt;Silver Arcade is also interesting because&amp;#160; we deliberately used a number of newer hipper technologies; including Azure, ASP.NET MVC, jQuery, MEF, NHibernate and so on.   &lt;br /&gt; &lt;a title="case study of Silver Arcade" href="http://visitmix.com/opencallvote/Entry?entryId=SILVER048" target="_blank"&gt;[vote for this]&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Thanks!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54940" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Game+Development/default.aspx">Game Development</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/fun/default.aspx">fun</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/XNA/default.aspx">XNA</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Software+Architecture/default.aspx">Software Architecture</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/web/default.aspx">web</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/MVC/default.aspx">MVC</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Presentations/default.aspx">Presentations</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/UI/default.aspx">UI</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/UI+Patterns/default.aspx">UI Patterns</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/XAML/default.aspx">XAML</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/UX/default.aspx">UX</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/viewmodel/default.aspx">viewmodel</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/mvvm/default.aspx">mvvm</category></item><item><title>thinking out loud: asp.net mvc &amp; nhaml</title><link>http://devlicio.us/blogs/christopher_bennage/archive/2009/10/02/thinking-out-loud-asp-net-mvc-amp-nhaml.aspx</link><pubDate>Fri, 02 Oct 2009 20:48:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:51989</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>9</slash:comments><description>&lt;p&gt;I’ve been playing around with the view engine &lt;a title=".NET implementation of the popular Rails Haml view engine" href="http://code.google.com/p/nhaml/" target="_blank"&gt;nhaml&lt;/a&gt; and asp.net mvc. At the same time, I’m playing around with some architectural ideas in hope to benefit future projects.&lt;/p&gt;  &lt;p&gt;I’m not doing any fancy yet, but I thought that it might be interesting to show you a couple of things to see what you think. Bear in mind, this is my sandbox code. I also suspect that I’m reinventing some wheels.&lt;/p&gt;  &lt;p&gt;The context here is a page that allows a user to register for an account on the site.&lt;/p&gt;  &lt;p&gt;First, the view looks like this:&lt;/p&gt;  &lt;pre&gt;%h2 Create Account

%form{method=&amp;quot;post&amp;quot;}
  = Html.FormField&amp;lt;OpenAccount&amp;gt;(x=&amp;gt;x.AccountName)
  = Html.FormField&amp;lt;OpenAccount&amp;gt;(x=&amp;gt;x.EmailAddress)
  = Html.FormField&amp;lt;OpenAccount&amp;gt;(x=&amp;gt;x.Password)
  
  %input {type=&amp;quot;submit&amp;quot; value=&amp;quot;Save&amp;quot;}
  %button {onclick=&amp;quot;javascript:history.back()&amp;quot; type=&amp;quot;button&amp;quot;} Cancel&lt;/pre&gt;

&lt;p&gt;OpenAccount is my view model. (I hate how we’ve overloaded these&amp;#160; terms.)&lt;/p&gt;

&lt;p&gt;I really like the succinctness of the nhaml, though I’m not ready to commit to it 100%. &lt;a href="http://dev.dejardin.org/" target="_blank"&gt;Spark&lt;/a&gt; is very attractive to me as well.&lt;/p&gt;

&lt;p&gt;Html.FormField is an extension method I wrote. I’m toying with the idea of having it emit a &amp;lt;lablel /&amp;gt; paired with the &amp;lt;input /&amp;gt;. Part of my motivation here is standardizing all of the label/inputs in my forms as well as a few experimental ideas about localization. &lt;/p&gt;

&lt;p&gt;It’s rather naive at the moment, but here is the helper:&lt;/p&gt;

&lt;pre class="c#:nogutter:nocontrols" name="code"&gt;public static string FormField&amp;lt;T&amp;gt;(this HtmlHelper helper, Expression&amp;lt;Func&amp;lt;T, string&amp;gt;&amp;gt; property)
    where T : class, ICommand
{
    var model = helper.ViewData.Model as T;
    if (helper.ViewData.Model != null &amp;amp;&amp;amp; model == null) throw new InvalidOperationException();

    var expression = (MemberExpression)property.Body;
    var name = expression.Member.Name;

    var value = (model == null)
                    ? null
                    : property.Compile().Invoke(model);

    return helper.TextBox(name, value);
}&lt;/pre&gt;

&lt;p&gt;Yeah, I hardcoded to a textbox for the moment. As I said, this is just a sandbox spike.&lt;/p&gt;

&lt;p&gt;Finally, the associated controller action looks like this:&lt;/p&gt;

&lt;pre class="c#:nogutter:nocontrols" name="code"&gt;[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(OpenAccount form)
{
    var result = _backend.Execute(form);

    return result.Success
               ? (ActionResult) RedirectToAction(&amp;quot;WhateverIsNext&amp;quot;)
               : View(result);
}&lt;/pre&gt;

&lt;p&gt;I’m treating the incoming form as a command. The _backend is responsible for processing the command. The command is just information necessary to execute the command, not the logic to execute it. The result I’m getting back is actually an instance of the same command with information attached by the backend (e.g., did the command execute correctly, what were the validation errors). It’s not exactly &lt;a title="single responsibility principle" href="http://en.wikipedia.org/wiki/Single_responsibility_principle" target="_blank"&gt;SRP&lt;/a&gt;, however I’m influenced by the simplicity of RoR here. &lt;/p&gt;

&lt;p&gt;One more interesting bit. I really don’t like having actions in my controller that do nothing other than render the view. For example:&lt;/p&gt;

&lt;pre class="c#:nogutter:nocontrols" name="code"&gt;[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Create()
{
    return View();
}&lt;/pre&gt;

&lt;p&gt;So instead, I created a base controller that does this:&lt;/p&gt;

&lt;pre class="c#:nogutter:nocontrols" name="code"&gt;public class ControllerBase : Controller
{
    protected override void HandleUnknownAction(string actionName)
    {
        try
        {
            View(actionName).ExecuteResult(ControllerContext);
        }
        catch (InvalidOperationException e)
        {
            //show the error or something
        }
    }
}&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=51989" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/MVC/default.aspx">MVC</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/nhaml/default.aspx">nhaml</category></item><item><title>The Influence of MVC on my WPF</title><link>http://devlicio.us/blogs/christopher_bennage/archive/2009/05/06/the-influence-of-mvc-on-my-wpf.aspx</link><pubDate>Wed, 06 May 2009 19:48:01 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:46528</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>9</slash:comments><description>&lt;p&gt;I was introduced to MVC as a pattern for Web development through &lt;a href="http://www.castleproject.org/monorail/" target="_blank"&gt;Castle MonoRail&lt;/a&gt;. From there I studied a bit of &lt;a href="http://rubyonrails.org/" target="_blank"&gt;Ruby on Rails&lt;/a&gt; (not enough) as well as the general philosophy of &lt;a href="http://www.37signals.com/" target="_blank"&gt;37signals&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;As I mentioned before, I thought I was moving away from Web development. However, the dive into ASP.NET MVC that &lt;a title="Silver Arcade, a free online gaming community" href="http://www.silverarcade.com/" target="_blank"&gt;Silver Arcade&lt;/a&gt; brought about has roped me back in.&lt;/p&gt;  &lt;p&gt;My work during the day (and some nights too) is still WPF though. I’ve discovered that MVC thinking has seeped into my WPF development.&lt;/p&gt;  &lt;h3&gt;Convention Over Configuration&lt;/h3&gt;  &lt;p&gt;A characteristic of most MVC frameworks is &lt;a href="http://en.wikipedia.org/wiki/Convention_over_Configuration" target="_blank"&gt;Convention Over Configuration&lt;/a&gt;. In short, it means that your “environment” makes assumptions about what you want and that you only need to be explicit about the exceptions.&lt;/p&gt;  &lt;p&gt;A practical example of this is the way that the View for an Action is inferred from the name of the Controller and Action. After creating your Action, you create a folder for the controller and and view that matches the name of the action. It just works. If you need to make exception, you can.&lt;/p&gt;  &lt;h3&gt;An Example in WPF&lt;/h3&gt;  &lt;p&gt;In our WPF development we employ a number of &lt;a title="I strongly dislike the term MVVM." href="http://msdn.microsoft.com/en-us/library/cc707862.aspx" target="_blank"&gt;Separated Presentation&lt;/a&gt; patterns. One of the more common patterns we use is MVP (in particular, the flavor of MVP implemented in &lt;a title="free WPF and Silverlight from the stone" href="http://www.codeplex.com/caliburn"&gt;Caliburn&lt;/a&gt;, which is really Supervising Controller).&lt;/p&gt;  &lt;p&gt;Imagine a simple contact manager application. We can add new contacts, view a list of all contacts, and open individual contacts for viewing or editing. We can open as many individual contacts as we like.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;margin-left:0px;border-top:0px;margin-right:0px;border-right:0px;" title="mvc" border="0" alt="mvc" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/christopher_5F00_bennage/mvc_5F00_313933F1.png" width="539" height="511" /&gt; &lt;/p&gt;  &lt;p&gt;Let’s say that there are buttons to open up the “Add New” view and “All Contacts” view. We can open an existing contact by double-clicking on them in the “All Contacts” view. &lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width:0px;margin:0px 8px 0px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="my imaginary solution" border="0" alt="my imaginary solution" align="left" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/christopher_5F00_bennage/56200930845PM_5F00_24D92471.png" width="271" height="341" /&gt;My solution setup for this imaginary (and highly contrived) application might look like this.&lt;/p&gt;  &lt;p&gt;ApplicationPresenter would be the root object of my UI. It would have an ObservableCollection of IPresenter that would be bound to a TabControl in Shell.xaml. Likewise, ApplicationPresenter will have a CurrentPresenter of IPresenter that will be bound to the SelectedItem on the TabControl. &lt;/p&gt;  &lt;p&gt;Shell.xaml is my only window in this example. All of the other views are user controls. I named it “shell” because I think of it as the outermost level of the views. Shell’s data context is set to ApplicationPresenter.&lt;/p&gt;  &lt;p&gt;I’m not going to dive too much deeper into this, because I want to get to my real point.&lt;/p&gt;  &lt;p&gt;My presenters don’t know anything about their views. It’s up to data binding to render each presenter with the correct view. This means that I need to create data templates for each of the presenters. Not such a big deal in a small application, but it can get tedious as the application grows.&lt;/p&gt;  &lt;p&gt;Hmmm… This structure is beginning to look a lot like an MVC app. Perhaps I can have it automatically infer my data templates for me?&lt;/p&gt;  &lt;h3&gt;Some Code&lt;/h3&gt;  &lt;p&gt;Yes we can. Here’s a &lt;em&gt;very naiveté&lt;/em&gt; bit of code that will do just that. It makes some big assumptions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;all of your presenters implement IPresenter &lt;/li&gt;    &lt;li&gt;all of your presenters are in a namespace containing “.Presenters” &lt;/li&gt;    &lt;li&gt;all of your views are in an analogous namespace containing in “.Views” &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Again, this is &lt;strong&gt;&lt;em&gt;not&lt;/em&gt;&lt;/strong&gt; production ready code, just my spike to prove the idea works. Please feel free to make suggestions.&lt;/p&gt;  &lt;pre class="c#:nogutter:nocontrols" name="code"&gt;public static class MvpConfiguration
{
    /// &amp;lt;summary&amp;gt;
    /// Creates a set of data templates pair to presenter classes based on naming conventions.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;remarks&amp;gt;If a data template is already present in the resources, then it is skipped.&amp;lt;/remarks&amp;gt;
    /// &amp;lt;param name=&amp;quot;resources&amp;quot;&amp;gt;The ResourceDictionary that the data templates for the views will be added to.&amp;lt;/param&amp;gt;
    public static void InferViewsFromPresenters(ResourceDictionary resources)
    {
        var lookup = MatchPresentersToViews();

        foreach (var pair in lookup)
        {
            var template = CreateDataTemplate(pair.Value, pair.Key);
            if (resources.Contains(template.DataTemplateKey)) continue;
            resources.Add(template.DataTemplateKey, template);
        }
    }

    private static Dictionary&amp;lt;Type, Type&amp;gt; MatchPresentersToViews()
    {
        var presenters = from type in Assembly.GetExecutingAssembly().GetTypes()
                         where typeof (IPresenter).IsAssignableFrom(type)
                         select type;

        var first = presenters.FirstOrDefault();
        if (first == null) throw new Exception(&amp;quot;I expected to find at least one presenters!&amp;quot;);

        string viewNamespace = first.Namespace
            .Replace(&amp;quot;.Presenters&amp;quot;, &amp;quot;.Views&amp;quot;);
        viewNamespace = viewNamespace.Substring(0, viewNamespace.IndexOf(&amp;quot;.Views&amp;quot;)+6);
        //yeah, that was hackish

        var views = from view in Assembly.GetExecutingAssembly().GetTypes()
                    where !string.IsNullOrEmpty(view.Namespace)
                          &amp;amp;&amp;amp; view.Namespace.StartsWith(viewNamespace)
                    select view;

        var table = new Dictionary&amp;lt;Type, Type&amp;gt;();

        foreach (var view in views)
        {
            var presenter = GetPresenterForView(view, presenters);
            if(presenter == null) continue;

            table.Add(presenter,view);
        }

        return table;
    }

    private static Type GetPresenterForView(Type type, IEnumerable&amp;lt;Type&amp;gt; presenters)
    {
        string name = type.Name.Replace(&amp;quot;View&amp;quot;, &amp;quot;Presenter&amp;quot;);
        var presenter =
            presenters.Where(p =&amp;gt; p.Name == name).FirstOrDefault();
        return presenter;
    }

    private static DataTemplate CreateDataTemplate(Type viewType, Type dataType)
    {
        var template = new DataTemplate(dataType);

        var factory = new FrameworkElementFactory(viewType);
        template.VisualTree = factory;
        return template;
    }
}&lt;/pre&gt;

&lt;p&gt;To use this, in your App.xaml.cs within OnStartup() add:&lt;/p&gt;

&lt;pre class="c#:nogutter:nocontrols" name="code"&gt;MvpConfiguration.InferViewsFromPresenters(Resources);&lt;/pre&gt;

&lt;p&gt;What do you think? Am I totally nuts?&lt;/p&gt;

&lt;p&gt;Oh, and I should also point out that &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelementfactory.aspx" target="_blank"&gt;FrameworkElementFactory&lt;/a&gt; is actually deprecated. :-( Caveat emptor.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=46528" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/MVC/default.aspx">MVC</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/data+templates/default.aspx">data templates</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/UI+Patterns/default.aspx">UI Patterns</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Caliburn/default.aspx">Caliburn</category></item><item><title>Shared Hosting &amp; The Bleeding Edge</title><link>http://devlicio.us/blogs/christopher_bennage/archive/2008/09/25/shared-hosting-amp-the-bleeding-edge.aspx</link><pubDate>Thu, 25 Sep 2008 15:58:56 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:42441</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>11</slash:comments><description>&lt;p&gt;So we&amp;#39;ve been working on a web project for a friend&amp;#39;s startup company (I don&amp;#39;t like doing work for my friends, but that&amp;#39;s a different matter). Since he has no technological preference and since we are such bleeding edge kinda guys (&lt;em&gt;the Achilles&amp;#39; Heel of ALT.NET?&lt;/em&gt;), we decided to build the site with the following: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://www.codeplex.com/aspnet/Wiki/View.aspx?title=MVC&amp;amp;referringTitle=Home" target="_blank"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="212" alt="Careful, don&amp;#39;t cut yourself." src="http://devlicious.com/blogs/christopher_bennage/WindowsLiveWriter/SharedHostingTheBleedingEdge_94C8/iStock_000005472751XSmall_3.jpg" width="320" align="right" border="0" /&gt;ASP.NET MVC&lt;/a&gt;  &lt;li&gt;&lt;a href="http://www.codeplex.com/MVCContrib" target="_blank"&gt;MVC Contrib&lt;/a&gt;  &lt;li&gt;&lt;a href="http://www.castleproject.org/container/index.html" target="_blank"&gt;Castle Windsor&lt;/a&gt;  &lt;li&gt;&lt;a href="http://www.hibernate.org/343.html" target="_blank"&gt;NHibernate&lt;/a&gt;  &lt;li&gt;&lt;a href="http://code.google.com/p/fluent-nhibernate/" target="_blank"&gt;Fluent NHibernate&lt;/a&gt; (this rocks) &lt;li&gt;NHibernate.Linq (part of &lt;a href="http://sourceforge.net/projects/nhcontrib/" target="_blank"&gt;NHibernate Contrib&lt;/a&gt;) (this rocks as well)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Castle and NHibernate (as you likely know) are mature products. So in keeping with our bleeding theme, we decided to use the trunk for these instead of the most recent release.&lt;/p&gt; &lt;p&gt;Despite all the blood, the development process was pretty smooth. I had a minor learning curve with MVC and a slightly less minor curve with some of the other bits, but all in all, it went well. (I am omitting a lengthy struggle writing a query because it is embarrassing how my &lt;strike&gt;SQL&lt;/strike&gt; query writing skills have atrophied.)&lt;/p&gt; &lt;p&gt;Ok, well, the time to deploy to the production site comes. Remember I said that this was a friend&amp;#39;s startup and there is little money to go around, so the production site is going be hosted at &lt;a href="http://www.crystaltech.com/" target="_blank"&gt;CrystalTech&lt;/a&gt;. I deploy the site, and -- nothing. It doesn&amp;#39;t work in the shared hosting environment.&lt;/p&gt; &lt;p&gt;We&amp;#39;re not used to having our applications run in a shared environment; most of our clients have dedicated hardware. If I had spent any amount of time thinking about it, I would have realized the forthcoming pain.&lt;/p&gt; &lt;p&gt;Unfortunately, I will not be able to present you with a step-by-step way to &lt;span&gt;make the pieces fit&lt;/span&gt;, the pain has blurred my memory. However, I will give you a general outline that I believe you will find helpful.&lt;/p&gt; &lt;h3&gt;Windows 2008, IIS 7, and Routing&lt;/h3&gt; &lt;p&gt;Most shared hosting environments are not running on Windows 2008 and that means no IIS 7. If you are using routing with MVC to get your Rails-style urls (and who isn&amp;#39;t?), routing is not going to work without IIS7. You can still get your MVC app to run, but&amp;nbsp; you have to call the view explicitly (something like \root\views\home\index.aspx).&lt;/p&gt; &lt;p&gt;I didn&amp;#39;t really think about this because the web server built-in to Visual Studio handles the routing correctly. (Even though I&amp;#39;ve run into a similar problem using MonoRail years ago).&lt;/p&gt; &lt;p&gt;CrystalTech (at the time of writing) only has &lt;em&gt;one server&lt;/em&gt; running IIS 7 and only &lt;em&gt;one plan&lt;/em&gt; available for that server. I didn&amp;#39;t think about this when my buddy signed up for the account, and I had to ask them to relocated the site to the 2008 server.&lt;/p&gt; &lt;p&gt;&lt;a href="http://anglicangeek.com/" target="_blank"&gt;Drew&lt;/a&gt; suggested that I ask the host to do a &lt;a href="http://professionalaspnet.com/archive/2007/07/27/Configure-IIS-for-Wildcard-Extensions-in-ASP.NET.aspx" target="_blank"&gt;wildcard mapping&lt;/a&gt; instead of moving the site over to IIS 7. This would work, but CrystalTech won&amp;#39;t to do it. I had actually tried to get them to do this a while back when I first started learning MonoRail.&lt;/p&gt; &lt;h3&gt;Partial Trust&lt;/h3&gt; &lt;p&gt;Shared hosting environment have to restrict security. If not, you could write your application to&lt;em&gt; do bad things&lt;/em&gt; to their server. Limited trust can prevent you from using lots nifty tricks that you may be used to. For example, application running under &lt;a href="http://msdn.microsoft.com/en-us/library/ms998341.aspx" target="_blank"&gt;Medium Trust&lt;/a&gt; cannot use reflection. Luckily, many hosts don&amp;#39;t lock you down that tight.&lt;/p&gt; &lt;p&gt;The real problem is that by default &lt;a href="http://msdn.microsoft.com/en-us/library/wd40t7ad.aspx" target="_blank"&gt;strongly named assemblies&lt;/a&gt; cannot be called by assemblies executing under less than Full Trust. For example, the Castle assemblies are strongly-named and thus they are not callable by your application in most typical shared environments. &lt;/p&gt; &lt;p&gt;The solution, if you have access to the source, is to use &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.allowpartiallytrustedcallersattribute.aspx" target="_blank"&gt;AllowPartiallyTrustedCallersAttribute&lt;/a&gt;. Just slap that bad boy into your AssemblyInfo.cs and your strongly named assembly can then be called.&lt;/p&gt; &lt;p&gt;Fortunately, Castle makes this easy. You execute the build script with something like this:&lt;/p&gt;&lt;pre&gt;nant -t:net-2.0 -D:assembly.allow-partially-trusted-callers=true release&lt;/pre&gt;
&lt;p&gt;I believe NHibernate has the attribute by default, but any other assembly that is strongly-named will need this attribute, and then you will want to recompile all the dependencies after adding the attribute.&lt;/p&gt;
&lt;h3&gt;The Nutshell&lt;/h3&gt;
&lt;p&gt;If you have to use a shared hosting environment,&lt;em&gt; talk to the host&lt;/em&gt;. Tell them what you are planning on doing. Secondly, visit the forums for the host and search them to see if someone is doing what you plan to do.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=42441" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Castle+Project/default.aspx">Castle Project</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Tips+_2600_amp_3B00_+Tricks/default.aspx">Tips &amp;amp; Tricks</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/ALT.NET/default.aspx">ALT.NET</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/MVC/default.aspx">MVC</category></item></channel></rss>