MonoRail, AspView and ReSharper: skip ViewAtDesignTime
May 24, 2008 at 1:53 AM
AspView and Intellisense
AspView is a MonoRail viewengine which provides compile time checking of views and Intellisense support in Visual Studio. The latter is achieved by using the known ASP.NET WebForms syntax to define views, see below for an example:
It uses the @Page directive and sets the Inherits attribute to a base class called ViewAtDesignTime defined by AspView. This base class contains fake methods and properties that are similar to the ones that are available to the runtime view class - Caslte.MonoRail.Views.AspView.AspViewBase. The only purpose of the ViewAtDesignTimeClass is to make Visual Studio's Intellisense work. It does, as can be seen in the picture. Additionally the user can provide a custom pair of design time and runtime classes that derive from ViewAtDesignTime and AspViewBase.
However, there is a caveat. ViewAtDesignTime derives from System.Web.UI.Page. This is a requirement of Visual Studio to make Intellisense work. As a result Intellisense will show all members of Page, which is at least confusing. More likely, it's misleading as many of the Members won't be available in AspViewBase and will let compilation fail.
In the example above Intellisense shows members like DataBind which will not be available during compilation.
ReSharper to the rescue: skip ViewAtDesignTime
However, as Ken Egozi pointed out on the Castle Developer mailing list, if you use ReSharper (and you should) you can skip the ViewAtDesignTime class altogether and just use the AspViewBase class (or a derived class) in the view. ReSharper will still provide Intellisense. The list of members is much more reliable as those members will definitively be available during compilation.
Advantages of using the AspViewBase based class instead of ViewAtDesignTime:
- Get better Intellisense: Page members are ommitted
- Less code: if you provide your own base classes for views because you want to provide some extra members to the view (a good example would be the code generated by CodeGenerator) you do not have to provide a design time counterpart as well.
- More robust code: similarly, if you have to provide a runtime class and a design time class you have to ensure that both interfaces match exactly, otherwise the design support is misleading (this problem does actually happen). Without the design time view, only one interface has to be maintained.
- No Intellisense on dev machines without ReSharper (which is a good excuse to ask your boss for a R# licence anyway)
Thanks to Ken Egozi for this neat hint.