[AspView] Mapping design time view base class to runtime view basec lass

2 views
Skip to first unread message

Andre Loker

unread,
May 23, 2008, 12:08:18 PM5/23/08
to Castle Developer Group
Hi group (especially Ken),


The current approach of AspView to find the corresponding runtime time base class of a view base class is to use the same class name minus the AtDesignTime suffix. I'd like to have this configurable. My idea is this:

1. Configuration
Augment the AspView configuration like this:
<aspview saveFiles="true" autoRecompilation="true" debug="false" >
  ...
  <viewTypes designTimeSuffix="Design">
    <viewType designtime="MyDesignTimeView, MyAssembly" runtime="WebAppView, WebApp.View"/>
    <viewType designtime="MyDesignTimeView`1, MyAssembly" runtime="WebAppView`1, WebApp.View"/>
  </viewTypes>
</aspview>


a) override the default design time suffix, optional, default is AtDesignTime
b) provide specific mappings between a design time view and the runtime view base classes, optional, the default is to use name/suffix based mapping as it is done now.

2. IViewTypeMapper
An interface that maps the base classes of a design time view to that of the runtime view, something like
interface IViewTypeMapper {
    Type MapDesignTimeViewToRuntimeView(Type designTimeClass);
    void Configure(XmlNode viewTypesNode);
}

designTimeClass is parsed from the aspx views

3. class DefaultTypeMapper
Implements IViewTypeMapper and uses the following strategy to find the runtime base class:
- If any <viewType> nodes are configured and the provided designTimeClass matches any of those designtime attributes, return the type found at the runtime-attribute
- Else if the design time type uses the DesignTimeSuffix, remove the suffix to find a matching type (just like it's done now)
- Else use some default base classes (just like it's done now)

4. Extensibility
Again in the config:
<aspview saveFiles="true" autoRecompilation="true" debug="false" >
  ...
  <viewTypes designTimeSuffix="Design" mapper="MyTypeMapper, MyAssembly">
    ...

  </viewTypes>
</aspview>


The mapper attribute defines the IViewTypeMapper implementation to use (default is DefaultTypeMapper).

5. Usage
The IViewTypeMapper will be used in the DetermineBaseClassStep to find the base class.


What do you think? I'd be glad to implement those changes, however, I've some questions:
- I cannot access the current AspViewCompilerOptions from the DetermineBaseClassStep. Any ideas on how to access the config?
- It seems that "providers" are passed from the config but never used. Any chance I can hook into this?

Regards,
Andre



Victor Kornov

unread,
May 23, 2008, 12:18:13 PM5/23/08
to castle-pro...@googlegroups.com
IMO, IViewTypeMapper could be useful. Not sure about 1) where you configure suffixes.
It would help to hear your use case, why do you need this?

Andre Loker

unread,
May 23, 2008, 12:51:57 PM5/23/08
to castle-pro...@googlegroups.com
I actually do not need the full blown solution, all I want is the ability to use a very short name for the view base class in the @Page directive
<%@ Page Language="C#" Inherits="View" %>
or
<%@ Page Language="C#" Inherits="View<ISomeViewData>" %>

rather than
<%@ Page Language="C#" Inherits="ViewAtDesignTime<ISomeViewData>" %>

I find the extra typing a bit tedious. So I thought before hacking something into AspView that could make this work I could as well pull of a more sophisticated design that is flexible and extensible.

A second issue is that the runtime view base class has to be in the same namespace as the design time base class; or the required namespace has to be included using <system.web><pages><namespaces>

Regards,
Andre


Victor Kornov schrieb:

Ken Egozi

unread,
May 23, 2008, 1:37:17 PM5/23/08
to castle-pro...@googlegroups.com
the thing is - View would be the *real* base class for your view, (which inherits AspViewBase) while ViewAtDesignTime is a marker class used only to fool VS into supplying intellisense.

if you'd use Inherits="AndreBaseView<ISomefing>" it would just work, you just will lose some intellisense on vanilla VS, as VS wants base classes for .aspx files to be : Page.

btw, when using R#, you don't need to have the Inherits="" class to be a Page, thus you can simply use your real View base class, and get intellisense, and actually a better one, as the membrs of Page would not appear there.
--
Ken Egozi.
http://www.kenegozi.com/blog
http://www.musicglue.com
http://www.castleproject.org
http://www.mamaherb.com
http://www.gotfriends.co.il

Andre Loker

unread,
May 23, 2008, 2:04:58 PM5/23/08
to castle-pro...@googlegroups.com
Ken Egozi schrieb:

> the thing is - View would be the *real* base class for your view,
> (which inherits AspViewBase) while ViewAtDesignTime is a marker class
> used only to fool VS into supplying intellisense.
Yeah, I know how and why it's done. Maybe I was unclear in my naming. In
my scenario View would have been the *design time view* derived from
AspView.ViewAtDesignTime. As I like the name to be really short, I would
have created that View class in the root namespace:

class View : Castle.MonoRail.Views.AspView.ViewAtDesignTime {
// project specific stuff like e.g.
protected RootAreaNode Root {
get { throw new NotImplementedException(this.ToString()); }
}
}

The "real" view base class would have went into some other namespace like

namespace WebApp {
abstract class View : Castle.MonoRail.Views.AspView.AspViewBase {
// project specific stuff like e.g.
protected RootAreaNode Root {
get { return (RootAreaNode) Properties["Site"]; }
}
}
}

I could then refer to the design to view by <%@Page .. inherits="View"%>
(without namespace) and AspView would map the global::View to
WebApp.View for the runtime view during compilation. See, I'm awfully
lazy :-)


>
> btw, when using R#, you don't need to have the Inherits="" class to be
> a Page, thus you can simply use your real View base class, and get
> intellisense, and actually a better one, as the membrs of Page would
> not appear there.

That *is* great news :-) I did not realize R# would work with a class
not based on Page. Thanks for the hint! I think I'll stick to this
solution, works fine for me. Not only does it reduce the amount of code,
it also bypasses the problem mentioned here:
http://support.castleproject.org/browse/CONTRIB-127


Regards,
Andre

Ken Egozi

unread,
May 23, 2008, 4:34:04 PM5/23/08
to castle-pro...@googlegroups.com
gotcha. great idea - separate the Real and Mock classes by namespace.

A patch (that would keep current behaviour but will allow change through config) will probably be accepted.

Andre Loker

unread,
May 23, 2008, 8:02:18 PM5/23/08
to castle-pro...@googlegroups.com
> A patch (that would keep current behaviour but will allow change
> through config) will probably be accepted.

I'll see what I can do.

BTW: I dropped a blog post regarding your hint
http://blog.andreloker.de/post/2008/05/MonoRail-AspView-and-ReSharper-skip-ViewAtDesignTime.aspx
Let me know if I'm missing anything.

Regards,
Andre

Reply all
Reply to author
Forward
0 new messages